* Re: [resend][PATCH v5 05/10] ASoC: simple-card-utils: enable "label" on asoc_simple_card_parse_card_name
From: Kuninori Morimoto @ 2017-04-17 23:58 UTC (permalink / raw)
To: Rob Herring; +Cc: Mark Brown, Linux-ALSA, Simon, Linux-DT
In-Reply-To: <CAL_JsqKPJ6WF08hEtx2Y7Z5WqUXQ0OBOeohEaPujX891ksZS2A-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
Hi Rob
> > @@ -82,14 +82,24 @@ int asoc_simple_card_parse_card_name(struct snd_soc_card *card,
> > char *prefix)
> > {
> > char prop[128];
> > + char *names[] = {
> > + "label", "name"
> > + };
> > + int i;
> > int ret;
> >
> > - snprintf(prop, sizeof(prop), "%sname", prefix);
> > + if (!prefix)
> > + prefix = "";
> >
> > /* Parse the card name from DT */
> > - ret = snd_soc_of_parse_card_name(card, prop);
> > - if (ret < 0)
> > - return ret;
> > + for (i = 0; i < ARRAY_SIZE(names); i++) {
> > + snprintf(prop, sizeof(prop), "%s%s", prefix, names[i]);
>
> "<prefix>label" is not a valid property name.
This function will be used from many drivers.
Not only for OF-graph sound card.
OF-graph sound card will use it without prefix.
Best regards
---
Kuninori Morimoto
--
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
* [PATCH] rtc: ds1374: Add trickle charger device tree binding
From: Moritz Fischer @ 2017-04-17 22:40 UTC (permalink / raw)
To: rtc-linux-/JYPxA39Uh5TLH3MbocFFw
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, a.zummo-BfzFCNDTiLLj+vYz1yj4TQ,
alexandre.belloni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
Moritz Fischer
Introduce a device tree binding for specifying the trickle charger
configuration for ds1374. This is based on the code for ds13390.
Signed-off-by: Moritz Fischer <mdf-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
---
.../devicetree/bindings/rtc/dallas,ds1374.txt | 18 ++++++++
drivers/rtc/rtc-ds1374.c | 54 ++++++++++++++++++++++
2 files changed, 72 insertions(+)
create mode 100644 Documentation/devicetree/bindings/rtc/dallas,ds1374.txt
diff --git a/Documentation/devicetree/bindings/rtc/dallas,ds1374.txt b/Documentation/devicetree/bindings/rtc/dallas,ds1374.txt
new file mode 100644
index 0000000..4cf5bd7
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/dallas,ds1374.txt
@@ -0,0 +1,18 @@
+* Dallas DS1374 I2C Real-Time Clock / WDT
+
+Required properties:
+- compatible: Should contain "dallas,ds1374".
+- reg: I2C address for chip
+
+Optional properties:
+- trickle-resistor-ohms : Selected resistor for trickle charger
+ Values usable for ds1374 are 250, 2000, 4000
+ Should be given if trickle charger should be enabled
+- trickle-diode-disable : Do not use internal trickle charger diode
+ Should be given if internal trickle charger diode should be disabled
+Example:
+ ds1374: rtc@0 {
+ compatible = "dallas,ds1374";
+ trickle-resistor-ohms = <250>;
+ reg = <0>;
+ };
diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c
index 4cd115e..873475d 100644
--- a/drivers/rtc/rtc-ds1374.c
+++ b/drivers/rtc/rtc-ds1374.c
@@ -53,6 +53,13 @@
#define DS1374_REG_SR_AF 0x01 /* Alarm Flag */
#define DS1374_REG_TCR 0x09 /* Trickle Charge */
+#define DS1374_TRICKLE_CHARGER_ENABLE 0xA0
+#define DS1374_TRICKLE_CHARGER_250_OHM 0x01
+#define DS1374_TRICKLE_CHARGER_2K_OHM 0x02
+#define DS1374_TRICKLE_CHARGER_4K_OHM 0x03
+#define DS1374_TRICKLE_CHARGER_NO_DIODE 0x04
+#define DS1374_TRICKLE_CHARGER_DIODE 0x08
+
static const struct i2c_device_id ds1374_id[] = {
{ "ds1374", 0 },
{ }
@@ -597,6 +604,49 @@ static struct notifier_block ds1374_wdt_notifier = {
};
#endif /*CONFIG_RTC_DRV_DS1374_WDT*/
+
+static int ds1374_trickle_of_init(struct i2c_client *client)
+{
+ u32 ohms = 0;
+ u8 value;
+ int ret;
+
+ if (of_property_read_u32(client->dev.of_node, "trickle-resistor-ohms",
+ &ohms))
+ return 0;
+
+ /* Enable charger */
+ value = DS1374_TRICKLE_CHARGER_ENABLE;
+ if (of_property_read_bool(client->dev.of_node, "trickle-diode-disable"))
+ value |= DS1374_TRICKLE_CHARGER_NO_DIODE;
+ else
+ value |= DS1374_TRICKLE_CHARGER_DIODE;
+
+ /* Resistor select */
+ switch (ohms) {
+ case 250:
+ value |= DS1374_TRICKLE_CHARGER_250_OHM;
+ break;
+ case 2000:
+ value |= DS1374_TRICKLE_CHARGER_2K_OHM;
+ break;
+ case 4000:
+ value |= DS1374_TRICKLE_CHARGER_4K_OHM;
+ break;
+ default:
+ dev_warn(&client->dev,
+ "Unsupported ohm value %02ux in dt\n", ohms);
+ return -EINVAL;
+ }
+ dev_dbg(&client->dev, "Trickle charge value is 0x%02x\n", value);
+
+ ret = i2c_smbus_write_byte_data(client, DS1374_REG_TCR, value);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
/*
*****************************************************************************
*
@@ -620,6 +670,10 @@ static int ds1374_probe(struct i2c_client *client,
INIT_WORK(&ds1374->work, ds1374_work);
mutex_init(&ds1374->mutex);
+ ret = ds1374_trickle_of_init(client);
+ if (ret)
+ return ret;
+
ret = ds1374_check_rtc_status(client);
if (ret)
return ret;
--
2.7.4
--
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
---
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rtc-linux+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.
^ permalink raw reply related
* [PATCHv2 3/3] i2c: altera: Add Altera I2C Controller driver
From: thor.thayer-VuQAYsv1563Yd54FQh9/CA @ 2017-04-17 21:49 UTC (permalink / raw)
To: wsa-z923LK4zBo2bacvFa/9K2g, robh-DgEjT+Ai2ygdnm+yROfE0A
Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
thor.thayer-VuQAYsv1563Yd54FQh9/CA
In-Reply-To: <1492465743-8679-1-git-send-email-thor.thayer-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
From: Thor Thayer <thor.thayer-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
Add driver support for the Altera I2C Controller. The I2C
controller is soft IP for use in FPGAs.
Signed-off-by: Thor Thayer <thor.thayer-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
---
v2 Remove altr, from fifo-size to agree with bindings.
Change compatible string to "altr,softip-i2c"
---
drivers/i2c/busses/Kconfig | 10 +
drivers/i2c/busses/Makefile | 1 +
drivers/i2c/busses/i2c-altera.c | 509 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 520 insertions(+)
create mode 100644 drivers/i2c/busses/i2c-altera.c
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 144cbad..981ea48 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -326,6 +326,16 @@ config I2C_POWERMAC
comment "I2C system bus drivers (mostly embedded / system-on-chip)"
+config I2C_ALTERA
+ tristate "Altera Soft IP I2C"
+ depends on (ARCH_SOCFPGA || NIOS2) && OF
+ help
+ If you say yes to this option, support will be included for the
+ Altera Soft IP I2C interfaces on SoCFPGA and Nios2 architectures.
+
+ This driver can also be built as a module. If so, the module
+ will be called i2c-altera.
+
config I2C_AT91
tristate "Atmel AT91 I2C Two-Wire interface (TWI)"
depends on ARCH_AT91
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 30b6085..4eb5c82 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_I2C_HYDRA) += i2c-hydra.o
obj-$(CONFIG_I2C_POWERMAC) += i2c-powermac.o
# Embedded system I2C/SMBus host controller drivers
+obj-$(CONFIG_I2C_ALTERA) += i2c-altera.o
obj-$(CONFIG_I2C_AT91) += i2c-at91.o
obj-$(CONFIG_I2C_AU1550) += i2c-au1550.o
obj-$(CONFIG_I2C_AXXIA) += i2c-axxia.o
diff --git a/drivers/i2c/busses/i2c-altera.c b/drivers/i2c/busses/i2c-altera.c
new file mode 100644
index 0000000..662dec8
--- /dev/null
+++ b/drivers/i2c/busses/i2c-altera.c
@@ -0,0 +1,509 @@
+/*
+ * Copyright Intel Corporation (C) 2017.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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 should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Based on the i2c-axxia.c driver.
+ */
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#define ALTR_I2C_TFR_CMD 0x00 /* Transfer Command register */
+#define ALTR_I2C_TFR_CMD_STA BIT(9) /* send START before byte */
+#define ALTR_I2C_TFR_CMD_STO BIT(8) /* send STOP after byte */
+#define ALTR_I2C_TFR_CMD_RW_D BIT(0) /* Direction of transfer */
+#define ALTR_I2C_RX_DATA 0x04 /* RX data FIFO register */
+#define ALTR_I2C_CTRL 0x08 /* Control register */
+#define ALTR_I2C_CTRL_RXT_SHFT 4 /* RX FIFO Threshold */
+#define ALTR_I2C_CTRL_TCT_SHFT 2 /* TFER CMD FIFO Threshold */
+#define ALTR_I2C_CTRL_BSPEED BIT(1) /* Bus Speed (1=Fast) */
+#define ALTR_I2C_CTRL_EN BIT(0) /* Enable Core (1=Enable) */
+#define ALTR_I2C_ISER 0x0C /* Interrupt Status Enable register */
+#define ALTR_I2C_ISER_RXOF_EN BIT(4) /* Enable RX OVERFLOW IRQ */
+#define ALTR_I2C_ISER_ARB_EN BIT(3) /* Enable ARB LOST IRQ */
+#define ALTR_I2C_ISER_NACK_EN BIT(2) /* Enable NACK DET IRQ */
+#define ALTR_I2C_ISER_RXRDY_EN BIT(1) /* Enable RX Ready IRQ */
+#define ALTR_I2C_ISER_TXRDY_EN BIT(0) /* Enable TX Ready IRQ */
+#define ALTR_I2C_ISR 0x10 /* Interrupt Status register */
+#define ALTR_I2C_ISR_RXOF BIT(4) /* RX OVERFLOW IRQ */
+#define ALTR_I2C_ISR_ARB BIT(3) /* ARB LOST IRQ */
+#define ALTR_I2C_ISR_NACK BIT(2) /* NACK DET IRQ */
+#define ALTR_I2C_ISR_RXRDY BIT(1) /* RX Ready IRQ */
+#define ALTR_I2C_ISR_TXRDY BIT(0) /* TX Ready IRQ */
+#define ALTR_I2C_STATUS 0x14 /* Status register */
+#define ALTR_I2C_STAT_CORE BIT(0) /* Core Status (0=idle) */
+#define ALTR_I2C_TC_FIFO_LVL 0x18 /* Transfer FIFO LVL register */
+#define ALTR_I2C_RX_FIFO_LVL 0x1C /* Receive FIFO LVL register */
+#define ALTR_I2C_SCL_LOW 0x20 /* SCL low count register */
+#define ALTR_I2C_SCL_HIGH 0x24 /* SCL high count register */
+#define ALTR_I2C_SDA_HOLD 0x28 /* SDA hold count register */
+
+#define ALTR_I2C_ALL_IRQ (ALTR_I2C_ISR_RXOF | ALTR_I2C_ISR_ARB | \
+ ALTR_I2C_ISR_NACK | ALTR_I2C_ISR_RXRDY | \
+ ALTR_I2C_ISR_TXRDY)
+
+#define ALTR_I2C_THRESHOLD 0 /*IRQ Threshold at 1 element */
+#define ALTR_I2C_DFLT_FIFO_SZ 4
+#define ALTR_I2C_TIMEOUT 100
+#define ALTR_I2C_XFER_TIMEOUT (msecs_to_jiffies(250))
+
+/**
+ * altr_i2c_dev - I2C device context
+ * @base: pointer to register struct
+ * @msg: pointer to current message
+ * @msg_len: number of bytes transferred in msg
+ * @msg_err: error code for completed message
+ * @msg_complete: xfer completion object
+ * @dev: device reference
+ * @adapter: core i2c abstraction
+ * @i2c_clk: clock reference for i2c input clock
+ * @bus_clk_rate: current i2c bus clock rate
+ * @buf: ptr to msg buffer for easier use.
+ * @fifo_size: size of the FIFO passed in.
+ */
+struct altr_i2c_dev {
+ void __iomem *base;
+ struct i2c_msg *msg;
+ size_t msg_len;
+ int msg_err;
+ struct completion msg_complete;
+ struct device *dev;
+ struct i2c_adapter adapter;
+ struct clk *i2c_clk;
+ u32 bus_clk_rate;
+ u8 *buf;
+ unsigned int fifo_size;
+};
+
+static void i2c_int_disable(struct altr_i2c_dev *idev, u32 mask)
+{
+ u32 int_en = readl(idev->base + ALTR_I2C_ISER);
+
+ writel(int_en & ~mask, idev->base + ALTR_I2C_ISER);
+}
+
+static void i2c_int_enable(struct altr_i2c_dev *idev, u32 mask)
+{
+ u32 int_en = readl(idev->base + ALTR_I2C_ISER);
+
+ writel(int_en | mask, idev->base + ALTR_I2C_ISER);
+}
+
+static void i2c_int_clear(struct altr_i2c_dev *idev, u32 mask)
+{
+ u32 int_en = readl(idev->base + ALTR_I2C_ISR);
+
+ writel(int_en | mask, idev->base + ALTR_I2C_ISR);
+}
+
+static void altr_i2c_core_disable(struct altr_i2c_dev *idev)
+{
+ u32 tmp = readl(idev->base + ALTR_I2C_CTRL);
+
+ writel(tmp & ~ALTR_I2C_CTRL_EN, idev->base + ALTR_I2C_CTRL);
+}
+
+static void altr_i2c_core_enable(struct altr_i2c_dev *idev)
+{
+ u32 tmp = readl(idev->base + ALTR_I2C_CTRL);
+
+ writel(tmp | ALTR_I2C_CTRL_EN, idev->base + ALTR_I2C_CTRL);
+}
+
+static void altr_i2c_reset(struct altr_i2c_dev *idev)
+{
+ altr_i2c_core_disable(idev);
+ altr_i2c_core_enable(idev);
+}
+
+static void altr_i2c_recover(struct altr_i2c_dev *idev)
+{
+ altr_i2c_reset(idev);
+ /* Clock start bit + 8 bits + stop bit out */
+ writel(ALTR_I2C_TFR_CMD_STA | ALTR_I2C_TFR_CMD_STO,
+ idev->base + ALTR_I2C_TFR_CMD);
+ altr_i2c_reset(idev);
+
+ i2c_recover_bus(&idev->adapter);
+}
+
+static inline void altr_i2c_stop(struct altr_i2c_dev *idev)
+{
+ writel(ALTR_I2C_TFR_CMD_STO, idev->base + ALTR_I2C_TFR_CMD);
+}
+
+static void altr_i2c_init(struct altr_i2c_dev *idev)
+{
+ u32 divisor = clk_get_rate(idev->i2c_clk) / idev->bus_clk_rate;
+ u32 clk_mhz = clk_get_rate(idev->i2c_clk) / 1000000;
+ u32 tmp = (ALTR_I2C_THRESHOLD << ALTR_I2C_CTRL_RXT_SHFT) |
+ (ALTR_I2C_THRESHOLD << ALTR_I2C_CTRL_TCT_SHFT);
+ u32 t_high, t_low;
+
+ if (idev->bus_clk_rate <= 100000) {
+ tmp &= ~ALTR_I2C_CTRL_BSPEED;
+ /* Standard mode SCL 50/50 */
+ t_high = divisor * 1 / 2;
+ t_low = divisor * 1 / 2;
+ } else {
+ tmp |= ALTR_I2C_CTRL_BSPEED;
+ /* Fast mode SCL 33/66 */
+ t_high = divisor * 1 / 3;
+ t_low = divisor * 2 / 3;
+ }
+ writel(tmp, idev->base + ALTR_I2C_CTRL);
+
+ dev_dbg(idev->dev, "rate=%uHz per_clk=%uMHz -> ratio=1:%u\n",
+ idev->bus_clk_rate, clk_mhz, divisor);
+
+ /* Reset controller */
+ altr_i2c_reset(idev);
+
+ /* SCL High Time */
+ writel(t_high, idev->base + ALTR_I2C_SCL_HIGH);
+ /* SCL Low Time */
+ writel(t_low, idev->base + ALTR_I2C_SCL_LOW);
+ /* SDA Hold Time, 300ns */
+ writel(div_u64(300 * clk_mhz, 1000), idev->base + ALTR_I2C_SDA_HOLD);
+
+ /* Mask all master interrupt bits */
+ i2c_int_disable(idev, ~0);
+}
+
+static int i2c_m_rd(const struct i2c_msg *msg)
+{
+ return (msg->flags & I2C_M_RD) != 0;
+}
+
+/**
+ * altr_i2c_empty_rx_fifo - Fetch data from RX FIFO until end of
+ * transfer. Send a Stop bit on the last byte.
+ */
+static void altr_i2c_empty_rx_fifo(struct altr_i2c_dev *idev)
+{
+ size_t rx_fifo_avail = readl(idev->base + ALTR_I2C_RX_FIFO_LVL);
+ int bytes_to_transfer = min(rx_fifo_avail, idev->msg_len);
+
+ while (bytes_to_transfer-- > 0) {
+ *idev->buf++ = readl(idev->base + ALTR_I2C_RX_DATA);
+ if (idev->msg_len == 1)
+ altr_i2c_stop(idev);
+ else
+ writel(0, idev->base + ALTR_I2C_TFR_CMD);
+
+ idev->msg_len--;
+ }
+}
+
+/**
+ * altr_i2c_fill_tx_fifo - Fill TX FIFO from current message buffer.
+ * @return: Number of bytes left to transfer.
+ */
+static int altr_i2c_fill_tx_fifo(struct altr_i2c_dev *idev)
+{
+ size_t tx_fifo_avail = idev->fifo_size - readl(idev->base +
+ ALTR_I2C_TC_FIFO_LVL);
+ int bytes_to_transfer = min(tx_fifo_avail, idev->msg_len);
+ int ret = idev->msg_len - bytes_to_transfer;
+
+ while (bytes_to_transfer-- > 0) {
+ if (idev->msg_len == 1)
+ writel(ALTR_I2C_TFR_CMD_STO | *idev->buf++,
+ idev->base + ALTR_I2C_TFR_CMD);
+ else
+ writel(*idev->buf++, idev->base + ALTR_I2C_TFR_CMD);
+ idev->msg_len--;
+ }
+
+ return ret;
+}
+
+/**
+ * altr_i2c_wait_for_core_idle - After TX, check core idle for all bytes TX.
+ * @return: 0 on success or -ETIMEDOUT on timeout.
+ */
+static int altr_i2c_wait_for_core_idle(struct altr_i2c_dev *idev)
+{
+ unsigned long timeout = jiffies + msecs_to_jiffies(ALTR_I2C_TIMEOUT);
+
+ do {
+ if (time_after(jiffies, timeout)) {
+ dev_err(idev->dev, "Core Idle timeout\n");
+ return -ETIMEDOUT;
+ }
+ } while (readl(idev->base + ALTR_I2C_STATUS) & ALTR_I2C_STAT_CORE);
+
+ return 0;
+}
+
+static irqreturn_t altr_i2c_isr(int irq, void *_dev)
+{
+ struct altr_i2c_dev *idev = _dev;
+ /* Read IRQ status but only interested in Enabled IRQs. */
+ u32 status = readl(idev->base + ALTR_I2C_ISR) &
+ readl(idev->base + ALTR_I2C_ISER);
+
+ if (!idev->msg) {
+ dev_warn(idev->dev, "unexpected interrupt\n");
+ goto out;
+ }
+
+ /* handle Lost Arbitration */
+ if (unlikely(status & ALTR_I2C_ISR_ARB)) {
+ dev_err(idev->dev, "%s: arbitration lost\n", __func__);
+ i2c_int_clear(idev, ALTR_I2C_ISR_ARB);
+ idev->msg_err = -EAGAIN;
+ goto complete;
+ }
+
+ if (unlikely(status & ALTR_I2C_ISR_NACK)) {
+ dev_dbg(idev->dev, "%s: could not get ACK\n", __func__);
+ idev->msg_err = -ENXIO;
+ i2c_int_clear(idev, ALTR_I2C_ISR_NACK);
+ altr_i2c_stop(idev);
+ goto complete;
+ }
+
+ /* handle RX FIFO Overflow */
+ if (i2c_m_rd(idev->msg) && unlikely(status & ALTR_I2C_ISR_RXOF)) {
+ altr_i2c_empty_rx_fifo(idev);
+ i2c_int_clear(idev, ALTR_I2C_ISR_RXRDY);
+ altr_i2c_stop(idev);
+ dev_err(idev->dev, "%s: RX FIFO Overflow\n", __func__);
+ goto complete;
+ }
+
+ /* RX FIFO needs service? */
+ if (i2c_m_rd(idev->msg) && (status & ALTR_I2C_ISR_RXRDY)) {
+ altr_i2c_empty_rx_fifo(idev);
+ i2c_int_clear(idev, ALTR_I2C_ISR_RXRDY);
+ if (!idev->msg_len)
+ goto complete;
+
+ goto out;
+ }
+
+ /* TX FIFO needs service? */
+ if (!i2c_m_rd(idev->msg) && (status & ALTR_I2C_ISR_TXRDY)) {
+ i2c_int_clear(idev, ALTR_I2C_ISR_TXRDY);
+ if (!altr_i2c_fill_tx_fifo(idev))
+ goto complete;
+
+ goto out;
+ }
+
+complete:
+ dev_dbg(idev->dev, "%s: Message Complete\n", __func__);
+ if (altr_i2c_wait_for_core_idle(idev))
+ dev_err(idev->dev, "%s: message timeout\n", __func__);
+ i2c_int_disable(idev, ALTR_I2C_ALL_IRQ);
+ i2c_int_clear(idev, ALTR_I2C_ALL_IRQ);
+ complete(&idev->msg_complete);
+
+out:
+ return IRQ_HANDLED;
+}
+
+static int altr_i2c_xfer_msg(struct altr_i2c_dev *idev, struct i2c_msg *msg)
+{
+ u32 int_mask = ALTR_I2C_ISR_RXOF | ALTR_I2C_ISR_ARB | ALTR_I2C_ISR_NACK;
+ u32 addr = (msg->addr << 1) & 0xFF;
+ unsigned long time_left;
+
+ idev->msg = msg;
+ idev->msg_len = msg->len;
+ idev->buf = msg->buf;
+ idev->msg_err = 0;
+ reinit_completion(&idev->msg_complete);
+ altr_i2c_core_enable(idev);
+
+ if (i2c_m_rd(msg)) {
+ /* Dummy read to ensure RX FIFO is empty */
+ readl(idev->base + ALTR_I2C_RX_DATA);
+ addr |= ALTR_I2C_TFR_CMD_RW_D;
+ }
+
+ writel(ALTR_I2C_TFR_CMD_STA | addr, idev->base + ALTR_I2C_TFR_CMD);
+
+ if (i2c_m_rd(msg)) {
+ /* write the first byte to start the RX */
+ writel(0, idev->base + ALTR_I2C_TFR_CMD);
+ int_mask |= ALTR_I2C_ISER_RXOF_EN | ALTR_I2C_ISER_RXRDY_EN;
+ } else {
+ altr_i2c_fill_tx_fifo(idev);
+ int_mask |= ALTR_I2C_ISR_TXRDY;
+ }
+ i2c_int_enable(idev, int_mask);
+
+ time_left = wait_for_completion_timeout(&idev->msg_complete,
+ ALTR_I2C_XFER_TIMEOUT);
+
+ i2c_int_disable(idev, int_mask);
+
+ if (readl(idev->base + ALTR_I2C_STATUS) & ALTR_I2C_STAT_CORE)
+ dev_err(idev->dev, "%s: Core Status not IDLE...\n", __func__);
+
+ if (time_left == 0) {
+ idev->msg_err = -ETIMEDOUT;
+ dev_err(idev->dev, "%s: Transaction timed out.\n", __func__);
+ altr_i2c_recover(idev);
+ }
+
+ if (unlikely(idev->msg_err) && idev->msg_err != -ENXIO)
+ altr_i2c_init(idev);
+
+ altr_i2c_core_disable(idev);
+
+ return idev->msg_err;
+}
+
+static int
+altr_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
+{
+ struct altr_i2c_dev *idev = i2c_get_adapdata(adap);
+ int i;
+ int ret = 0;
+
+ for (i = 0; ret == 0 && i < num; ++i)
+ ret = altr_i2c_xfer_msg(idev, &msgs[i]);
+
+ return ret ? : i;
+}
+
+static u32 altr_i2c_func(struct i2c_adapter *adap)
+{
+ return I2C_FUNC_I2C;
+}
+
+static const struct i2c_algorithm altr_i2c_algo = {
+ .master_xfer = altr_i2c_xfer,
+ .functionality = altr_i2c_func,
+};
+
+static int altr_i2c_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct altr_i2c_dev *idev = NULL;
+ struct resource *res;
+ int irq;
+ int ret = 0;
+
+ idev = devm_kzalloc(&pdev->dev, sizeof(*idev), GFP_KERNEL);
+ if (!idev)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ idev->base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(idev->base))
+ return PTR_ERR(idev->base);
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(&pdev->dev, "missing interrupt resource\n");
+ return irq;
+ }
+
+ idev->i2c_clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(idev->i2c_clk)) {
+ dev_err(&pdev->dev, "missing clock\n");
+ return PTR_ERR(idev->i2c_clk);
+ }
+
+ idev->dev = &pdev->dev;
+ init_completion(&idev->msg_complete);
+
+ if (of_property_read_u32(np, "fifo-size", &idev->fifo_size))
+ idev->fifo_size = ALTR_I2C_DFLT_FIFO_SZ;
+
+ if (of_property_read_u32(np, "clock-frequency", &idev->bus_clk_rate))
+ idev->bus_clk_rate = 100000; /* default clock rate */
+
+ if (idev->bus_clk_rate > 400000) {
+ dev_err(&pdev->dev, "invalid clock-frequency %d\n",
+ idev->bus_clk_rate);
+ return -EINVAL;
+ }
+
+ ret = devm_request_irq(&pdev->dev, irq, altr_i2c_isr, 0,
+ pdev->name, idev);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to claim IRQ%d\n", irq);
+ return ret;
+ }
+
+ ret = clk_prepare_enable(idev->i2c_clk);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to enable clock\n");
+ return ret;
+ }
+
+ altr_i2c_init(idev);
+
+ i2c_set_adapdata(&idev->adapter, idev);
+ strlcpy(idev->adapter.name, pdev->name, sizeof(idev->adapter.name));
+ idev->adapter.owner = THIS_MODULE;
+ idev->adapter.algo = &altr_i2c_algo;
+ idev->adapter.dev.parent = &pdev->dev;
+ idev->adapter.dev.of_node = pdev->dev.of_node;
+
+ platform_set_drvdata(pdev, idev);
+
+ ret = i2c_add_adapter(&idev->adapter);
+ if (ret) {
+ clk_disable_unprepare(idev->i2c_clk);
+ return ret;
+ }
+ dev_info(&pdev->dev, "Altera SoftIP I2C Probe Complete\n");
+
+ return 0;
+}
+
+static int altr_i2c_remove(struct platform_device *pdev)
+{
+ struct altr_i2c_dev *idev = platform_get_drvdata(pdev);
+
+ clk_disable_unprepare(idev->i2c_clk);
+ i2c_del_adapter(&idev->adapter);
+
+ return 0;
+}
+
+/* Match table for of_platform binding */
+static const struct of_device_id altr_i2c_of_match[] = {
+ { .compatible = "altr,softip-i2c" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, altr_i2c_of_match);
+
+static struct platform_driver altr_i2c_driver = {
+ .probe = altr_i2c_probe,
+ .remove = altr_i2c_remove,
+ .driver = {
+ .name = "altera-i2c",
+ .of_match_table = altr_i2c_of_match,
+ },
+};
+
+module_platform_driver(altr_i2c_driver);
+
+MODULE_DESCRIPTION("Altera Soft IP I2C bus driver");
+MODULE_AUTHOR("Thor Thayer <thor.thayer-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>");
+MODULE_LICENSE("GPL v2");
--
1.9.1
--
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
* [PATCHv2 2/3] dt-bindings: i2c: Add Altera I2C Controller
From: thor.thayer-VuQAYsv1563Yd54FQh9/CA @ 2017-04-17 21:49 UTC (permalink / raw)
To: wsa-z923LK4zBo2bacvFa/9K2g, robh-DgEjT+Ai2ygdnm+yROfE0A
Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
thor.thayer-VuQAYsv1563Yd54FQh9/CA
In-Reply-To: <1492465743-8679-1-git-send-email-thor.thayer-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
From: Thor Thayer <thor.thayer-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
Add the documentation to support the Altera synthesizable
logic I2C Controller.
Signed-off-by: Thor Thayer <thor.thayer-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
---
v2 Change the subject to identify dt-bindings
Add synthesizable logic to description.
Change compatible string to "altr,softip-i2c"
Make description of clock phandle singular since 1 clock.
Remove altr, from fifo-size
Specify fifo-size is in bytes.
---
.../devicetree/bindings/i2c/i2c-altera.txt | 38 ++++++++++++++++++++++
1 file changed, 38 insertions(+)
create mode 100644 Documentation/devicetree/bindings/i2c/i2c-altera.txt
diff --git a/Documentation/devicetree/bindings/i2c/i2c-altera.txt b/Documentation/devicetree/bindings/i2c/i2c-altera.txt
new file mode 100644
index 0000000..ba25b1ea
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/i2c-altera.txt
@@ -0,0 +1,38 @@
+* Altera I2C Controller
+* This is Altera's synthesizable logic block I2C Controller.
+
+Required properties :
+ - compatible : should be "altr,softip-i2c"
+ - reg : Offset and length of the register set for the device
+ - interrupts : <IRQ> where IRQ is the interrupt number.
+ - clocks : phandle to input clock.
+ - #address-cells = <1>;
+ - #size-cells = <0>;
+
+Recommended properties :
+ - clock-frequency : desired I2C bus clock frequency in Hz.
+
+Optional properties :
+ - fifo-size : Size of the RX and TX FIFOs in bytes.
+ - Child nodes conforming to i2c bus binding
+
+Example :
+
+ i2c@100080000 {
+ compatible = "altr,softip-i2c";
+ reg = <0x00000001 0x00080000 0x00000040>;
+ interrupt-parent = <&intc>;
+ interrupts = <0 43 4>;
+ clocks = <&clk_0>;
+ clock-frequency = <100000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ fifo-size = <4>;
+
+ eeprom@51 {
+ compatible = "atmel,24c32";
+ reg = <0x51>;
+ pagesize = <32>;
+ };
+ };
+
--
1.9.1
--
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
* [PATCHv2 1/3] MAINTAINERS: Add Altera I2C Controller Driver
From: thor.thayer-VuQAYsv1563Yd54FQh9/CA @ 2017-04-17 21:49 UTC (permalink / raw)
To: wsa-z923LK4zBo2bacvFa/9K2g, robh-DgEjT+Ai2ygdnm+yROfE0A
Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
thor.thayer-VuQAYsv1563Yd54FQh9/CA
In-Reply-To: <1492465743-8679-1-git-send-email-thor.thayer-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
From: Thor Thayer <thor.thayer-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
Add maintainer for the Altera I2C Controller Driver.
Signed-off-by: Thor Thayer <thor.thayer-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
---
v2 No change
---
MAINTAINERS | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 4bfaea4..e654d34 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -636,6 +636,11 @@ ALPS PS/2 TOUCHPAD DRIVER
R: Pali Rohár <pali.rohar-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
F: drivers/input/mouse/alps.*
+ALTERA I2C CONTROLLER DRIVER
+M: Thor Thayer <thor.thayer-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
+S: Maintained
+F: drivers/i2c/busses/i2c-altera.c
+
ALTERA MAILBOX DRIVER
M: Ley Foon Tan <lftan-EIB2kfCEclfQT0dZR+AlfA@public.gmane.org>
L: nios2-dev-g9ZBwUv/Ih/yUk5EbOjzuce+I+R0W71w@public.gmane.org (moderated for non-subscribers)
--
1.9.1
--
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
* [PATCHv2 0/3] Add Altera I2C Controller Driver
From: thor.thayer-VuQAYsv1563Yd54FQh9/CA @ 2017-04-17 21:49 UTC (permalink / raw)
To: wsa-z923LK4zBo2bacvFa/9K2g, robh-DgEjT+Ai2ygdnm+yROfE0A
Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
thor.thayer-VuQAYsv1563Yd54FQh9/CA
From: Thor Thayer <thor.thayer-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
Add the Altera soft IP I2C Controller driver for use in FPGAs.
Thor Thayer (3):
MAINTAINERS: Add Altera I2C Controller Driver
dt-bindings: i2c: Add Altera I2C Controller
i2c: altera: Add Altera I2C Controller driver
.../devicetree/bindings/i2c/i2c-altera.txt | 38 ++
MAINTAINERS | 5 +
drivers/i2c/busses/Kconfig | 10 +
drivers/i2c/busses/Makefile | 1 +
drivers/i2c/busses/i2c-altera.c | 509 +++++++++++++++++++++
5 files changed, 563 insertions(+)
create mode 100644 Documentation/devicetree/bindings/i2c/i2c-altera.txt
create mode 100644 drivers/i2c/busses/i2c-altera.c
--
1.9.1
--
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
* [PATCH 1/1] ARM: dts: meson: Extend L2 cache controller node for Meson8 and Meson8b
From: Martin Blumenstingl @ 2017-04-17 21:42 UTC (permalink / raw)
To: linux-amlogic-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
khilman-rdvid1DuHRBWk0Htik3J/w, carlo-KA+7E9HrN00dnm+yROfE0A
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA, linux-I+IVW8TIWO2tmTQ+vhA3Yw,
mark.rutland-5wv7dgnIgG8, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
Carlo Caione, Martin Blumenstingl
In-Reply-To: <20170417214244.23698-1-martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
From: Carlo Caione <carlo-6IF/jdPJHihWk0Htik3J/w@public.gmane.org>
This patch extends the L2 cache controller node for the Amlogic Meson8
and Meson8b SoCs with some missing parameters. These are taken from the
Amlogic GPL kernel source.
Signed-off-by: Carlo Caione <carlo-6IF/jdPJHihWk0Htik3J/w@public.gmane.org>
[apply the change to Meson8 and Meson8b and updated description]
Signed-off-by: Martin Blumenstingl <martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
---
arch/arm/boot/dts/meson8.dtsi | 6 ++++++
arch/arm/boot/dts/meson8b.dtsi | 6 ++++++
2 files changed, 12 insertions(+)
diff --git a/arch/arm/boot/dts/meson8.dtsi b/arch/arm/boot/dts/meson8.dtsi
index 5eaaf067c76a..6993077331c7 100644
--- a/arch/arm/boot/dts/meson8.dtsi
+++ b/arch/arm/boot/dts/meson8.dtsi
@@ -188,6 +188,12 @@
clocks = <&clk81>;
};
+&L2 {
+ arm,data-latency = <3 3 3>;
+ arm,tag-latency = <2 2 2>;
+ arm,filter-ranges = <0x100000 0xc0000000>;
+};
+
&spifc {
clocks = <&clk81>;
};
diff --git a/arch/arm/boot/dts/meson8b.dtsi b/arch/arm/boot/dts/meson8b.dtsi
index ef9ac974111c..d9f116a418b2 100644
--- a/arch/arm/boot/dts/meson8b.dtsi
+++ b/arch/arm/boot/dts/meson8b.dtsi
@@ -171,6 +171,12 @@
};
};
+&L2 {
+ arm,data-latency = <3 3 3>;
+ arm,tag-latency = <2 2 2>;
+ arm,filter-ranges = <0x100000 0xc0000000>;
+};
+
&uart_AO {
clocks = <&clkc CLKID_CLK81>;
};
--
2.12.2
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 0/1] add missing L2 cache properties for Meson8 and Meson8b
From: Martin Blumenstingl @ 2017-04-17 21:42 UTC (permalink / raw)
To: linux-amlogic-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
khilman-rdvid1DuHRBWk0Htik3J/w, carlo-KA+7E9HrN00dnm+yROfE0A
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA, linux-I+IVW8TIWO2tmTQ+vhA3Yw,
mark.rutland-5wv7dgnIgG8, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
Martin Blumenstingl
This adds three missing L2 cache properties for the cache controller
on Meson8 and Meson8b.
This patch was originally written by Carlo Caione, I just took it and
applied it to Meson8 as well and rebased it.
This patch is based on my previous series from [0]: "Amlogic Meson (32-bit)
.dts cleanups"
[0] http://lists.infradead.org/pipermail/linux-amlogic/2017-April/003399.html
Carlo Caione (1):
ARM: dts: meson: Extend L2 cache controller node for Meson8 and
Meson8b
arch/arm/boot/dts/meson8.dtsi | 6 ++++++
arch/arm/boot/dts/meson8b.dtsi | 6 ++++++
2 files changed, 12 insertions(+)
--
2.12.2
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH 2/2] ARM: dts: meson8b: inherit meson.dtsi from meson8b.dtsi
From: Martin Blumenstingl @ 2017-04-17 21:39 UTC (permalink / raw)
To: linux-amlogic-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
khilman-rdvid1DuHRBWk0Htik3J/w, carlo-KA+7E9HrN00dnm+yROfE0A,
mark.rutland-5wv7dgnIgG8, robh+dt-DgEjT+Ai2ygdnm+yROfE0A
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA, linux-I+IVW8TIWO2tmTQ+vhA3Yw,
Martin Blumenstingl
In-Reply-To: <20170417213938.22626-1-martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
Currently only meson6.dtsi and meson8.dtsi inherit the generic
meson.dtsi. However, since the Meson8b platform is basically a slightly
updated version of Meson8 we can safely inherit meson.dtsi. An indicator
for this are the nodes which are identical in meson.dtsi and
meson8b.dtsi (L2, gic, timer, uart_AO, uart_A, uart_B, uart_C).
Additionally this makes the following devices available on Meson8b which
were not avaialble before (however, since all affected drivers support
Meson6, Meson8 and the whole GX series there's no reason to assume that
they are not working):
- i2c_a and i2c_B
- the IR receiver
- SPFIC (SPI flash controller)
- the dwmac ethernet controller
Differences between Meson8 and Meson8b seem to be:
- ARM Cortex-A5 core instead of Cortex-A9 on Meson8
- dwmac on Meson8b supports RGMII
- small pinctrl updates
Inheriting meson.dtsi makes it easier to maintain by removing duplicate
definitions.
Signed-off-by: Martin Blumenstingl <martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
---
arch/arm/boot/dts/meson8b.dtsi | 210 +++++++++++++++++------------------------
1 file changed, 84 insertions(+), 126 deletions(-)
diff --git a/arch/arm/boot/dts/meson8b.dtsi b/arch/arm/boot/dts/meson8b.dtsi
index 828aa49c678c..ef9ac974111c 100644
--- a/arch/arm/boot/dts/meson8b.dtsi
+++ b/arch/arm/boot/dts/meson8b.dtsi
@@ -47,11 +47,9 @@
#include <dt-bindings/clock/meson8b-clkc.h>
#include <dt-bindings/gpio/meson8b-gpio.h>
#include <dt-bindings/reset/amlogic,meson8b-reset.h>
-#include "skeleton.dtsi"
+#include "meson.dtsi"
/ {
- interrupt-parent = <&gic>;
-
cpus {
#address-cells = <1>;
#size-cells = <0>;
@@ -84,147 +82,107 @@
reg = <0x203>;
};
};
+}; /* end of / */
- soc {
- compatible = "simple-bus";
+&aobus {
+ pinctrl_aobus: pinctrl@84 {
+ compatible = "amlogic,meson8b-aobus-pinctrl";
+ reg = <0x84 0xc>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
- L2: l2-cache-controller@c4200000 {
- compatible = "arm,pl310-cache";
- reg = <0xc4200000 0x1000>;
- cache-unified;
- cache-level = <2>;
+ gpio_ao: ao-bank@14 {
+ reg = <0x14 0x4>,
+ <0x2c 0x4>,
+ <0x24 0x8>;
+ reg-names = "mux", "pull", "gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinctrl_aobus 0 130 16>;
};
- gic: interrupt-controller@c4301000 {
- compatible = "arm,cortex-a9-gic";
- reg = <0xc4301000 0x1000>,
- <0xc4300100 0x0100>;
- interrupt-controller;
- #interrupt-cells = <3>;
- };
-
- reset: reset-controller@c1104404 {
- compatible = "amlogic,meson8b-reset";
- reg = <0xc1104404 0x20>;
- #reset-cells = <1>;
- };
-
- wdt: watchdog@c1109900 {
- compatible = "amlogic,meson8b-wdt";
- reg = <0xc1109900 0x8>;
- interrupts = <0 0 1>;
+ uart_ao_a_pins: uart_ao_a {
+ mux {
+ groups = "uart_tx_ao_a", "uart_rx_ao_a";
+ function = "uart_ao";
+ };
};
+ };
+};
- timer@c1109940 {
- compatible = "amlogic,meson6-timer";
- reg = <0xc1109940 0x18>;
- interrupts = <0 10 1>;
- };
+&cbus {
+ clkc: clock-controller@4000 {
+ #clock-cells = <1>;
+ compatible = "amlogic,meson8b-clkc";
+ reg = <0x8000 0x4>, <0x4000 0x460>;
+ };
- uart_AO: serial@c81004c0 {
- compatible = "amlogic,meson-uart";
- reg = <0xc81004c0 0x18>;
- interrupts = <0 90 1>;
- clocks = <&clkc CLKID_CLK81>;
- status = "disabled";
- };
+ reset: reset-controller@4404 {
+ compatible = "amlogic,meson8b-reset";
+ reg = <0x4404 0x20>;
+ #reset-cells = <1>;
+ };
- uart_A: serial@c11084c0 {
- compatible = "amlogic,meson-uart";
- reg = <0xc11084c0 0x18>;
- interrupts = <0 26 1>;
- clocks = <&clkc CLKID_CLK81>;
- status = "disabled";
- };
+ pwm_ab: pwm@8550 {
+ compatible = "amlogic,meson8b-pwm";
+ reg = <0x8550 0x10>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
- uart_B: serial@c11084dc {
- compatible = "amlogic,meson-uart";
- reg = <0xc11084dc 0x18>;
- interrupts = <0 75 1>;
- clocks = <&clkc CLKID_CLK81>;
- status = "disabled";
- };
+ pwm_cd: pwm@8650 {
+ compatible = "amlogic,meson8b-pwm";
+ reg = <0x8650 0x10>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
- uart_C: serial@c1108700 {
- compatible = "amlogic,meson-uart";
- reg = <0xc1108700 0x18>;
- interrupts = <0 93 1>;
- clocks = <&clkc CLKID_CLK81>;
- status = "disabled";
- };
+ pwm_ef: pwm@86c0 {
+ compatible = "amlogic,meson8b-pwm";
+ reg = <0x86c0 0x10>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
- clkc: clock-controller@c1104000 {
- #clock-cells = <1>;
- compatible = "amlogic,meson8b-clkc";
- reg = <0xc1108000 0x4>, <0xc1104000 0x460>;
- };
+ wdt: watchdog@9900 {
+ compatible = "amlogic,meson8b-wdt";
+ reg = <0x9900 0x8>;
+ interrupts = <0 0 1>;
+ };
- pwm_ab: pwm@8550 {
- compatible = "amlogic,meson8b-pwm";
- reg = <0xc1108550 0x10>;
- #pwm-cells = <3>;
- status = "disabled";
- };
+ pinctrl_cbus: pinctrl@9880 {
+ compatible = "amlogic,meson8b-cbus-pinctrl";
+ reg = <0x9880 0x10>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
- pwm_cd: pwm@8650 {
- compatible = "amlogic,meson8b-pwm";
- reg = <0xc1108650 0x10>;
- #pwm-cells = <3>;
- status = "disabled";
+ gpio: banks@80b0 {
+ reg = <0x80b0 0x28>,
+ <0x80e8 0x18>,
+ <0x8120 0x18>,
+ <0x8030 0x38>;
+ reg-names = "mux", "pull", "pull-enable", "gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinctrl_cbus 0 0 130>;
};
+ };
+};
- pwm_ef: pwm@86c0 {
- compatible = "amlogic,meson8b-pwm";
- reg = <0xc11086c0 0x10>;
- #pwm-cells = <3>;
- status = "disabled";
- };
+&uart_AO {
+ clocks = <&clkc CLKID_CLK81>;
+};
- pinctrl_cbus: pinctrl@c1109880 {
- compatible = "amlogic,meson8b-cbus-pinctrl";
- reg = <0xc1109880 0x10>;
- #address-cells = <1>;
- #size-cells = <1>;
- ranges;
-
- gpio: banks@c11080b0 {
- reg = <0xc11080b0 0x28>,
- <0xc11080e8 0x18>,
- <0xc1108120 0x18>,
- <0xc1108030 0x38>;
- reg-names = "mux", "pull", "pull-enable", "gpio";
- gpio-controller;
- #gpio-cells = <2>;
- gpio-ranges = <&pinctrl_cbus 0 0 130>;
- };
- };
+&uart_A {
+ clocks = <&clkc CLKID_CLK81>;
+};
- pinctrl_aobus: pinctrl@c8100084 {
- compatible = "amlogic,meson8b-aobus-pinctrl";
- reg = <0xc8100084 0xc>;
- #address-cells = <1>;
- #size-cells = <1>;
- ranges;
-
- gpio_ao: ao-bank@c1108030 {
- reg = <0xc8100014 0x4>,
- <0xc810002c 0x4>,
- <0xc8100024 0x8>;
- reg-names = "mux", "pull", "gpio";
- gpio-controller;
- #gpio-cells = <2>;
- gpio-ranges = <&pinctrl_aobus 0 130 16>;
- };
+&uart_B {
+ clocks = <&clkc CLKID_CLK81>;
+};
- uart_ao_a_pins: uart_ao_a {
- mux {
- groups = "uart_tx_ao_a", "uart_rx_ao_a";
- function = "uart_ao";
- };
- };
- };
- };
-}; /* end of / */
+&uart_C {
+ clocks = <&clkc CLKID_CLK81>;
+};
--
2.12.2
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 1/2] ARM: dts: meson: organize devices in their corresponding busses
From: Martin Blumenstingl @ 2017-04-17 21:39 UTC (permalink / raw)
To: linux-amlogic-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
khilman-rdvid1DuHRBWk0Htik3J/w, carlo-KA+7E9HrN00dnm+yROfE0A,
mark.rutland-5wv7dgnIgG8, robh+dt-DgEjT+Ai2ygdnm+yROfE0A
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA, linux-I+IVW8TIWO2tmTQ+vhA3Yw,
Martin Blumenstingl
In-Reply-To: <20170417213938.22626-1-martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
The Amlogic Meson SoCs have most of the internal peripherals organized
in busses. Use them to make the dts easier to read and to avoid
duplicated register (bus) offset definitions.
The bus information is taken from the vendor kernel:
#define IO_CBUS_PHY_BASE 0xc1100000 ///2M
#define IO_AOBUS_PHY_BASE 0xc8100000 ///1M
There are more internal busses (such as the abp bus which seems to
contain audio, HDMI and Mali registers), but since we don't have
drivers for them yet these are not added (yet).
Signed-off-by: Martin Blumenstingl <martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
---
arch/arm/boot/dts/meson.dtsi | 180 ++++++++++++++++++++++--------------------
arch/arm/boot/dts/meson6.dtsi | 2 -
arch/arm/boot/dts/meson8.dtsi | 116 ++++++++++++++++++---------
3 files changed, 171 insertions(+), 127 deletions(-)
diff --git a/arch/arm/boot/dts/meson.dtsi b/arch/arm/boot/dts/meson.dtsi
index 8c77c87660cd..9701bd1bc298 100644
--- a/arch/arm/boot/dts/meson.dtsi
+++ b/arch/arm/boot/dts/meson.dtsi
@@ -65,110 +65,116 @@
#interrupt-cells = <3>;
};
- timer@c1109940 {
- compatible = "amlogic,meson6-timer";
- reg = <0xc1109940 0x18>;
- interrupts = <0 10 1>;
- };
-
soc {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
ranges;
- wdt: watchdog@c1109900 {
- compatible = "amlogic,meson6-wdt";
- reg = <0xc1109900 0x8>;
- interrupts = <0 0 1>;
- };
-
- uart_AO: serial@c81004c0 {
- compatible = "amlogic,meson-uart";
- reg = <0xc81004c0 0x18>;
- interrupts = <0 90 1>;
- clocks = <&clk81>;
- status = "disabled";
- };
-
- uart_A: serial@c11084c0 {
- compatible = "amlogic,meson-uart";
- reg = <0xc11084c0 0x18>;
- interrupts = <0 26 1>;
- clocks = <&clk81>;
- status = "disabled";
- };
-
- uart_B: serial@c11084dc {
- compatible = "amlogic,meson-uart";
- reg = <0xc11084dc 0x18>;
- interrupts = <0 75 1>;
- clocks = <&clk81>;
- status = "disabled";
- };
-
- uart_C: serial@c1108700 {
- compatible = "amlogic,meson-uart";
- reg = <0xc1108700 0x18>;
- interrupts = <0 93 1>;
- clocks = <&clk81>;
- status = "disabled";
- };
-
- i2c_AO: i2c@c8100500 {
- compatible = "amlogic,meson6-i2c";
- reg = <0xc8100500 0x20>;
- interrupts = <0 92 1>;
- clocks = <&clk81>;
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
- };
-
- i2c_A: i2c@c1108500 {
- compatible = "amlogic,meson6-i2c";
- reg = <0xc1108500 0x20>;
- interrupts = <0 21 1>;
- clocks = <&clk81>;
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
- };
-
- i2c_B: i2c@c11087c0 {
- compatible = "amlogic,meson6-i2c";
- reg = <0xc11087c0 0x20>;
- interrupts = <0 128 1>;
- clocks = <&clk81>;
+ cbus: cbus@c1100000 {
+ compatible = "simple-bus";
+ reg = <0xc1100000 0x200000>;
#address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
+ #size-cells = <1>;
+ ranges = <0x0 0xc1100000 0x200000>;
+
+ uart_A: serial@84c0 {
+ compatible = "amlogic,meson-uart";
+ reg = <0x84c0 0x18>;
+ interrupts = <0 26 1>;
+ status = "disabled";
+ };
+
+ uart_B: serial@84dc {
+ compatible = "amlogic,meson-uart";
+ reg = <0x84dc 0x18>;
+ interrupts = <0 75 1>;
+ status = "disabled";
+ };
+
+ i2c_A: i2c@8500 {
+ compatible = "amlogic,meson6-i2c";
+ reg = <0x8500 0x20>;
+ interrupts = <0 21 1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ uart_C: serial@8700 {
+ compatible = "amlogic,meson-uart";
+ reg = <0x8700 0x18>;
+ interrupts = <0 93 1>;
+ status = "disabled";
+ };
+
+ i2c_B: i2c@87c0 {
+ compatible = "amlogic,meson6-i2c";
+ reg = <0x87c0 0x20>;
+ interrupts = <0 128 1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ spifc: spi@8c80 {
+ compatible = "amlogic,meson6-spifc";
+ reg = <0x8c80 0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ wdt: watchdog@9900 {
+ compatible = "amlogic,meson6-wdt";
+ reg = <0x9900 0x8>;
+ interrupts = <0 0 1>;
+ };
+
+ timer@9940 {
+ compatible = "amlogic,meson6-timer";
+ reg = <0x9940 0x18>;
+ interrupts = <0 10 1>;
+ };
};
- ir_receiver: ir-receiver@c8100480 {
- compatible= "amlogic,meson6-ir";
- reg = <0xc8100480 0x20>;
- interrupts = <0 15 1>;
- status = "disabled";
- };
-
- spifc: spi@c1108c80 {
- compatible = "amlogic,meson6-spifc";
- reg = <0xc1108c80 0x80>;
+ aobus: aobus@c8100000 {
+ compatible = "simple-bus";
+ reg = <0xc8100000 0x100000>;
#address-cells = <1>;
- #size-cells = <0>;
- clocks = <&clk81>;
- status = "disabled";
+ #size-cells = <1>;
+ ranges = <0x0 0xc8100000 0x100000>;
+
+ ir_receiver: ir-receiver@480 {
+ compatible= "amlogic,meson6-ir";
+ reg = <0x480 0x20>;
+ interrupts = <0 15 1>;
+ status = "disabled";
+ };
+
+ uart_AO: serial@4c0 {
+ compatible = "amlogic,meson-uart";
+ reg = <0x4c0 0x18>;
+ interrupts = <0 90 1>;
+ status = "disabled";
+ };
+
+ i2c_AO: i2c@500 {
+ compatible = "amlogic,meson6-i2c";
+ reg = <0x500 0x20>;
+ interrupts = <0 92 1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
};
ethmac: ethernet@c9410000 {
compatible = "amlogic,meson6-dwmac", "snps,dwmac";
reg = <0xc9410000 0x10000
- 0xc1108108 0x4>;
+ 0xc1108108 0x4>;
interrupts = <0 8 1>;
interrupt-names = "macirq";
- clocks = <&clk81>;
- clock-names = "stmmaceth";
status = "disabled";
};
};
diff --git a/arch/arm/boot/dts/meson6.dtsi b/arch/arm/boot/dts/meson6.dtsi
index 8b33be15af94..b0fc91ffd6a1 100644
--- a/arch/arm/boot/dts/meson6.dtsi
+++ b/arch/arm/boot/dts/meson6.dtsi
@@ -51,8 +51,6 @@
model = "Amlogic Meson6 SoC";
compatible = "amlogic,meson6";
- interrupt-parent = <&gic>;
-
cpus {
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/arm/boot/dts/meson8.dtsi b/arch/arm/boot/dts/meson8.dtsi
index ebc763eab195..5eaaf067c76a 100644
--- a/arch/arm/boot/dts/meson8.dtsi
+++ b/arch/arm/boot/dts/meson8.dtsi
@@ -50,8 +50,6 @@
model = "Amlogic Meson8 SoC";
compatible = "amlogic,meson8";
- interrupt-parent = <&gic>;
-
cpus {
#address-cells = <1>;
#size-cells = <0>;
@@ -91,18 +89,55 @@
clock-frequency = <141666666>;
};
- pinctrl_cbus: pinctrl@c1109880 {
+}; /* end of / */
+
+&aobus {
+ pinctrl_aobus: pinctrl@84 {
+ compatible = "amlogic,meson8-aobus-pinctrl";
+ reg = <0x84 0xc>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ gpio_ao: ao-bank@14 {
+ reg = <0x14 0x4>,
+ <0x2c 0x4>,
+ <0x24 0x8>;
+ reg-names = "mux", "pull", "gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinctrl_aobus 0 120 16>;
+ };
+
+ uart_ao_a_pins: uart_ao_a {
+ mux {
+ groups = "uart_tx_ao_a", "uart_rx_ao_a";
+ function = "uart_ao";
+ };
+ };
+
+ i2c_ao_pins: i2c_mst_ao {
+ mux {
+ groups = "i2c_mst_sck_ao", "i2c_mst_sda_ao";
+ function = "i2c_mst_ao";
+ };
+ };
+ };
+};
+
+&cbus {
+ pinctrl_cbus: pinctrl@9880 {
compatible = "amlogic,meson8-cbus-pinctrl";
- reg = <0xc1109880 0x10>;
+ reg = <0x9880 0x10>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
- gpio: banks@c11080b0 {
- reg = <0xc11080b0 0x28>,
- <0xc11080e8 0x18>,
- <0xc1108120 0x18>,
- <0xc1108030 0x30>;
+ gpio: banks@80b0 {
+ reg = <0x80b0 0x28>,
+ <0x80e8 0x18>,
+ <0x8120 0x18>,
+ <0x8030 0x30>;
reg-names = "mux", "pull", "pull-enable", "gpio";
gpio-controller;
#gpio-cells = <2>;
@@ -134,36 +169,41 @@
};
};
};
+};
- pinctrl_aobus: pinctrl@c8100084 {
- compatible = "amlogic,meson8-aobus-pinctrl";
- reg = <0xc8100084 0xc>;
- #address-cells = <1>;
- #size-cells = <1>;
- ranges;
+ðmac {
+ clocks = <&clk81>;
+ clock-names = "stmmaceth";
+};
- gpio_ao: ao-bank@c1108030 {
- reg = <0xc8100014 0x4>,
- <0xc810002c 0x4>,
- <0xc8100024 0x8>;
- reg-names = "mux", "pull", "gpio";
- gpio-controller;
- #gpio-cells = <2>;
- gpio-ranges = <&pinctrl_aobus 0 120 16>;
- };
+&i2c_AO {
+ clocks = <&clk81>;
+};
- uart_ao_a_pins: uart_ao_a {
- mux {
- groups = "uart_tx_ao_a", "uart_rx_ao_a";
- function = "uart_ao";
- };
- };
+&i2c_A {
+ clocks = <&clk81>;
+};
- i2c_ao_pins: i2c_mst_ao {
- mux {
- groups = "i2c_mst_sck_ao", "i2c_mst_sda_ao";
- function = "i2c_mst_ao";
- };
- };
- };
-}; /* end of / */
+&i2c_B {
+ clocks = <&clk81>;
+};
+
+&spifc {
+ clocks = <&clk81>;
+};
+
+&uart_AO {
+ clocks = <&clk81>;
+};
+
+&uart_A {
+ clocks = <&clk81>;
+};
+
+&uart_B {
+ clocks = <&clk81>;
+};
+
+&uart_C {
+ clocks = <&clk81>;
+};
--
2.12.2
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 0/2] Amlogic Meson (32-bit) .dts cleanups
From: Martin Blumenstingl @ 2017-04-17 21:39 UTC (permalink / raw)
To: linux-amlogic-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
khilman-rdvid1DuHRBWk0Htik3J/w, carlo-KA+7E9HrN00dnm+yROfE0A,
mark.rutland-5wv7dgnIgG8, robh+dt-DgEjT+Ai2ygdnm+yROfE0A
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA, linux-I+IVW8TIWO2tmTQ+vhA3Yw,
Martin Blumenstingl
This series provides a few cleanups in the 32-bit Amlogic .dts files.
The first patch introduces the actual busses so the .dts' basic structure
is similar to what we have in the 64-bit .dts files.
The second patch removes even more duplication by inheriting meson.dtsi
from meson8b.dtsi (just like meson6.dtsi and meson8.dtsi are doing).
There should not be any functional changes with these patches. However,
I was only test this on a Meson8 based device, so it would be great if
somebody could test this on a Meson8b device.
Martin Blumenstingl (2):
ARM: dts: meson: organize devices in their corresponding busses
ARM: dts: meson8b: inherit meson.dtsi from meson8b.dtsi
arch/arm/boot/dts/meson.dtsi | 180 ++++++++++++++++++-----------------
arch/arm/boot/dts/meson6.dtsi | 2 -
arch/arm/boot/dts/meson8.dtsi | 116 +++++++++++++++--------
arch/arm/boot/dts/meson8b.dtsi | 210 +++++++++++++++++------------------------
4 files changed, 255 insertions(+), 253 deletions(-)
--
2.12.2
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH 13/13] MIPS: lantiq: Remove the arch/mips/lantiq/xway/reset.c implementation
From: Martin Blumenstingl @ 2017-04-17 21:28 UTC (permalink / raw)
To: Hauke Mehrtens
Cc: ralf-6z/3iImG2C8G8FEW9MqTrA, linux-mips-6z/3iImG2C8G8FEW9MqTrA,
linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-watchdog-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA, john-Pj+rj9U5foFAfugRpC6u6w,
linux-spi-u79uwXL29TY76Z2rM5mHXA,
hauke.mehrtens-ral2JQCrhuEAvxtiuMwx3w
In-Reply-To: <20170417192942.32219-14-hauke-5/S+JYg5SzeELgA04lAiVw@public.gmane.org>
On Mon, Apr 17, 2017 at 9:29 PM, Hauke Mehrtens <hauke-5/S+JYg5SzeELgA04lAiVw@public.gmane.org> wrote:
> From: Martin Blumenstingl <martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
>
> The RCU register are now access through separates drivers. remove the
> last peaces of the old implementation.
s/peaces/pieces/
you should probably mention that arch/mips/kernel/reset.c handles the
ltq_machine_halt and ltq_machine_power_off code, while
ltq_machine_restart (setting some reset bits) can be replaced with
"syscon-reboot"
apart from that: great to see that this gets some love! :)
> Signed-off-by: Hauke Mehrtens <hauke-5/S+JYg5SzeELgA04lAiVw@public.gmane.org>
> ---
> arch/mips/lantiq/Kconfig | 1 +
> arch/mips/lantiq/xway/Makefile | 2 +-
> arch/mips/lantiq/xway/reset.c | 157 -----------------------------------------
> 3 files changed, 2 insertions(+), 158 deletions(-)
> delete mode 100644 arch/mips/lantiq/xway/reset.c
>
> diff --git a/arch/mips/lantiq/Kconfig b/arch/mips/lantiq/Kconfig
> index f5db4a426568..35bc69b78268 100644
> --- a/arch/mips/lantiq/Kconfig
> +++ b/arch/mips/lantiq/Kconfig
> @@ -18,6 +18,7 @@ config SOC_XWAY
> select SOC_TYPE_XWAY
> select HW_HAS_PCI
> select MFD_SYSCON
> + select MFD_CORE
>
> config SOC_FALCON
> bool "FALCON"
> diff --git a/arch/mips/lantiq/xway/Makefile b/arch/mips/lantiq/xway/Makefile
> index 6daf3149e7ca..fbb0747c70b7 100644
> --- a/arch/mips/lantiq/xway/Makefile
> +++ b/arch/mips/lantiq/xway/Makefile
> @@ -1,3 +1,3 @@
> -obj-y := prom.o sysctrl.o clk.o reset.o dma.o gptu.o dcdc.o
> +obj-y := prom.o sysctrl.o clk.o dma.o gptu.o dcdc.o
>
> obj-y += vmmc.o
> diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c
> deleted file mode 100644
> index 5aec1f54275b..000000000000
> --- a/arch/mips/lantiq/xway/reset.c
> +++ /dev/null
> @@ -1,157 +0,0 @@
> -/*
> - * 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.
> - *
> - * Copyright (C) 2010 John Crispin <john-Pj+rj9U5foFAfugRpC6u6w@public.gmane.org>
> - * Copyright (C) 2013-2015 Lantiq Beteiligungs-GmbH & Co.KG
> - */
> -
> -#include <linux/init.h>
> -#include <linux/io.h>
> -#include <linux/ioport.h>
> -#include <linux/pm.h>
> -#include <linux/export.h>
> -#include <linux/delay.h>
> -#include <linux/of_address.h>
> -#include <linux/of_platform.h>
> -#include <linux/reset-controller.h>
> -
> -#include <asm/reboot.h>
> -
> -#include <lantiq_soc.h>
> -
> -#include "../prom.h"
> -
> -/* reset request register */
> -#define RCU_RST_REQ 0x0010
> -/* reset status register */
> -#define RCU_RST_STAT 0x0014
> -
> -/* xbar BE flag */
> -#define RCU_AHB_ENDIAN 0x004C
> -#define RCU_VR9_BE_AHB1S 0x00000008
> -
> -/* reboot bit */
> -#define RCU_RD_GPHY0_XRX200 BIT(31)
> -#define RCU_RD_SRST BIT(30)
> -#define RCU_RD_GPHY1_XRX200 BIT(29)
> -
> -/* reset cause */
> -#define RCU_STAT_SHIFT 26
> -/* boot selection */
> -#define RCU_BOOT_SEL(x) ((x >> 18) & 0x7)
> -#define RCU_BOOT_SEL_XRX200(x) (((x >> 17) & 0xf) | ((x >> 8) & 0x10))
> -
> -/* dwc2 USB configuration registers */
> -#define RCU_USB1CFG 0x0018
> -#define RCU_USB2CFG 0x0034
> -
> -/* USB DMA endianness bits */
> -#define RCU_USBCFG_HDSEL_BIT BIT(11)
> -#define RCU_USBCFG_HOST_END_BIT BIT(10)
> -#define RCU_USBCFG_SLV_END_BIT BIT(9)
> -
> -/* USB reset bits */
> -#define RCU_USBRESET 0x0010
> -
> -#define USBRESET_BIT BIT(4)
> -
> -#define RCU_USBRESET2 0x0048
> -
> -#define USB1RESET_BIT BIT(4)
> -#define USB2RESET_BIT BIT(5)
> -
> -#define RCU_CFG1A 0x0038
> -#define RCU_CFG1B 0x003C
> -
> -/* USB PMU devices */
> -#define PMU_AHBM BIT(15)
> -#define PMU_USB0 BIT(6)
> -#define PMU_USB1 BIT(27)
> -
> -/* USB PHY PMU devices */
> -#define PMU_USB0_P BIT(0)
> -#define PMU_USB1_P BIT(26)
> -
> -/* remapped base addr of the reset control unit */
> -static void __iomem *ltq_rcu_membase;
> -static struct device_node *ltq_rcu_np;
> -static DEFINE_SPINLOCK(ltq_rcu_lock);
> -
> -static void ltq_rcu_w32(uint32_t val, uint32_t reg_off)
> -{
> - ltq_w32(val, ltq_rcu_membase + reg_off);
> -}
> -
> -static uint32_t ltq_rcu_r32(uint32_t reg_off)
> -{
> - return ltq_r32(ltq_rcu_membase + reg_off);
> -}
> -
> -static void ltq_rcu_w32_mask(uint32_t clr, uint32_t set, uint32_t reg_off)
> -{
> - unsigned long flags;
> -
> - spin_lock_irqsave(<q_rcu_lock, flags);
> - ltq_rcu_w32((ltq_rcu_r32(reg_off) & ~(clr)) | (set), reg_off);
> - spin_unlock_irqrestore(<q_rcu_lock, flags);
> -}
> -
> -static void ltq_machine_restart(char *command)
> -{
> - u32 val = ltq_rcu_r32(RCU_RST_REQ);
> -
> - if (of_device_is_compatible(ltq_rcu_np, "lantiq,rcu-xrx200"))
> - val |= RCU_RD_GPHY1_XRX200 | RCU_RD_GPHY0_XRX200;
> -
> - val |= RCU_RD_SRST;
> -
> - local_irq_disable();
> - ltq_rcu_w32(val, RCU_RST_REQ);
> - unreachable();
> -}
> -
> -static void ltq_machine_halt(void)
> -{
> - local_irq_disable();
> - unreachable();
> -}
> -
> -static void ltq_machine_power_off(void)
> -{
> - local_irq_disable();
> - unreachable();
> -}
> -
> -static int __init mips_reboot_setup(void)
> -{
> - struct resource res;
> -
> - ltq_rcu_np = of_find_compatible_node(NULL, NULL, "lantiq,rcu-xway");
> - if (!ltq_rcu_np)
> - ltq_rcu_np = of_find_compatible_node(NULL, NULL,
> - "lantiq,rcu-xrx200");
> -
> - /* check if all the reset register range is available */
> - if (!ltq_rcu_np)
> - panic("Failed to load reset resources from devicetree");
> -
> - if (of_address_to_resource(ltq_rcu_np, 0, &res))
> - panic("Failed to get rcu memory range");
> -
> - if (!request_mem_region(res.start, resource_size(&res), res.name))
> - pr_err("Failed to request rcu memory");
> -
> - ltq_rcu_membase = ioremap_nocache(res.start, resource_size(&res));
> - if (!ltq_rcu_membase)
> - panic("Failed to remap core memory");
> -
> - _machine_restart = ltq_machine_restart;
> - _machine_halt = ltq_machine_halt;
> - pm_power_off = ltq_machine_power_off;
> -
> - return 0;
> -}
> -
> -arch_initcall(mips_reboot_setup);
> --
> 2.11.0
>
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" 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 11/13] phy: Add an USB PHY driver for the Lantiq SoCs using the RCU module
From: Martin Blumenstingl @ 2017-04-17 21:23 UTC (permalink / raw)
To: Hauke Mehrtens
Cc: ralf-6z/3iImG2C8G8FEW9MqTrA, linux-mips-6z/3iImG2C8G8FEW9MqTrA,
linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-watchdog-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA, john-Pj+rj9U5foFAfugRpC6u6w,
linux-spi-u79uwXL29TY76Z2rM5mHXA,
hauke.mehrtens-ral2JQCrhuEAvxtiuMwx3w
In-Reply-To: <20170417192942.32219-12-hauke-5/S+JYg5SzeELgA04lAiVw@public.gmane.org>
On Mon, Apr 17, 2017 at 9:29 PM, Hauke Mehrtens <hauke-5/S+JYg5SzeELgA04lAiVw@public.gmane.org> wrote:
> From: Martin Blumenstingl <martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
>
> This driver starts the DWC2 core(s) built into the XWAY SoCs and provides
> the PHY interfaces for each core. The phy instances can be passed to the
> dwc2 driver, which already supports the generic phy interface.
>
> Signed-off-by: Hauke Mehrtens <hauke-5/S+JYg5SzeELgA04lAiVw@public.gmane.org>
you should probably send this patch to the PHY maintainer as well
(Kishon Vijay Abraham I <kishon-l0cyMroinI0@public.gmane.org>)
> ---
> .../bindings/phy/phy-lantiq-rcu-usb2.txt | 59 ++++
> arch/mips/lantiq/xway/reset.c | 43 ---
> arch/mips/lantiq/xway/sysctrl.c | 24 +-
> drivers/phy/Kconfig | 8 +
> drivers/phy/Makefile | 1 +
> drivers/phy/phy-lantiq-rcu-usb2.c | 325 +++++++++++++++++++++
> 6 files changed, 405 insertions(+), 55 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/phy/phy-lantiq-rcu-usb2.txt
> create mode 100644 drivers/phy/phy-lantiq-rcu-usb2.c
>
> diff --git a/Documentation/devicetree/bindings/phy/phy-lantiq-rcu-usb2.txt b/Documentation/devicetree/bindings/phy/phy-lantiq-rcu-usb2.txt
> new file mode 100644
> index 000000000000..0ec9f790b6e0
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/phy/phy-lantiq-rcu-usb2.txt
> @@ -0,0 +1,59 @@
> +Lantiq XWAY SoC RCU USB 1.1/2.0 PHY binding
> +===========================================
> +
> +This binding describes the USB PHY hardware provided by the RCU module on the
> +Lantiq XWAY SoCs.
> +
> +
> +-------------------------------------------------------------------------------
> +Required properties (controller (parent) node):
> +- compatible : Should be one of
> + "lantiq,ase-rcu-usb2-phy"
> + "lantiq,danube-rcu-usb2-phy"
> + "lantiq,xrx100-rcu-usb2-phy"
> + "lantiq,xrx200-rcu-usb2-phy"
> + "lantiq,xrx300-rcu-usb2-phy"
> +- lantiq,rcu-syscon : A phandle to the RCU module and the offsets to the
> + USB PHY configuration and USB MAC registers.
> +- address-cells : should be 1
> +- size-cells : should be 0
> +- phy-cells : from the generic PHY bindings, must be 1
> +
> +Optional properties (controller (parent) node):
> +- vbus-gpio : References a GPIO which enables VBUS all given USB
> + ports.
the PHY framework already handles this if you wrap the GPIO in a
"regulator-fixed" node, see [0] how to define a fixed regulator with a
GPIO (the regulator in this example has two states: off = 0V and on =
5V, probably exactly what you need) and [1] how to pass it to the PHY
(phy-core.c handles this already, no driver specific code needed)
> +
> +Required nodes : A sub-node is required for each USB PHY port.
> +
> +
> +-------------------------------------------------------------------------------
> +Required properties (port (child) node):
> +- reg : The ID of the USB port, usually 0 or 1.
> +- clocks : References to the (PMU) "ctrl" and "phy" clk gates.
> +- clock-names : Must be one of the following:
> + "ctrl"
> + "phy"
> +- resets : References to the RCU USB configuration reset bits.
> +- reset-names : Must be one of the following:
> + "analog-config" (optional)
> + "statemachine-soft" (optional)
> +
> +Optional properties (port (child) node):
> +- vbus-gpio : References a GPIO which enables VBUS for the USB port.
> +
> +
> +-------------------------------------------------------------------------------
> +Example for the USB PHYs on an xRX200 SoC:
> + usb_phys0: rcu-usb2-phy@0 {
> + compatible = "lantiq,xrx200-rcu-usb2-phy";
> + reg = <0>;
> +
> + lantiq,rcu-syscon = <&rcu0 0x18 0x38>;
> + clocks = <&pmu PMU_GATE_USB0_CTRL>,
> + <&pmu PMU_GATE_USB0_PHY>;
> + clock-names = "ctrl", "phy";
> + vbus-gpios = <&gpio 32 GPIO_ACTIVE_HIGH>;
> + resets = <&rcu_reset1 4>, <&rcu_reset0 4>;
> + reset-names = "phy", "ctrl";
> + #phy-cells = <0>;
> + };
> diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c
> index 3f30fb81a50f..5aec1f54275b 100644
> --- a/arch/mips/lantiq/xway/reset.c
> +++ b/arch/mips/lantiq/xway/reset.c
could these arch/mips/lantiq/xway/reset.c changes to into PATCH #3 as well?
> @@ -124,45 +124,6 @@ static void ltq_machine_power_off(void)
> unreachable();
> }
>
> -static void ltq_usb_init(void)
> -{
> - /* Power for USB cores 1 & 2 */
> - ltq_pmu_enable(PMU_AHBM);
> - ltq_pmu_enable(PMU_USB0);
> - ltq_pmu_enable(PMU_USB1);
> -
> - ltq_rcu_w32(ltq_rcu_r32(RCU_CFG1A) | BIT(0), RCU_CFG1A);
> - ltq_rcu_w32(ltq_rcu_r32(RCU_CFG1B) | BIT(0), RCU_CFG1B);
> -
> - /* Enable USB PHY power for cores 1 & 2 */
> - ltq_pmu_enable(PMU_USB0_P);
> - ltq_pmu_enable(PMU_USB1_P);
> -
> - /* Configure cores to host mode */
> - ltq_rcu_w32(ltq_rcu_r32(RCU_USB1CFG) & ~RCU_USBCFG_HDSEL_BIT,
> - RCU_USB1CFG);
> - ltq_rcu_w32(ltq_rcu_r32(RCU_USB2CFG) & ~RCU_USBCFG_HDSEL_BIT,
> - RCU_USB2CFG);
> -
> - /* Select DMA endianness (Host-endian: big-endian) */
> - ltq_rcu_w32((ltq_rcu_r32(RCU_USB1CFG) & ~RCU_USBCFG_SLV_END_BIT)
> - | RCU_USBCFG_HOST_END_BIT, RCU_USB1CFG);
> - ltq_rcu_w32(ltq_rcu_r32((RCU_USB2CFG) & ~RCU_USBCFG_SLV_END_BIT)
> - | RCU_USBCFG_HOST_END_BIT, RCU_USB2CFG);
> -
> - /* Hard reset USB state machines */
> - ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET) | USBRESET_BIT, RCU_USBRESET);
> - udelay(50 * 1000);
> - ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET) & ~USBRESET_BIT, RCU_USBRESET);
> -
> - /* Soft reset USB state machines */
> - ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET2)
> - | USB1RESET_BIT | USB2RESET_BIT, RCU_USBRESET2);
> - udelay(50 * 1000);
> - ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET2)
> - & ~(USB1RESET_BIT | USB2RESET_BIT), RCU_USBRESET2);
> -}
> -
> static int __init mips_reboot_setup(void)
> {
> struct resource res;
> @@ -186,10 +147,6 @@ static int __init mips_reboot_setup(void)
> if (!ltq_rcu_membase)
> panic("Failed to remap core memory");
>
> - if (of_machine_is_compatible("lantiq,ar9") ||
> - of_machine_is_compatible("lantiq,vr9"))
> - ltq_usb_init();
> -
> _machine_restart = ltq_machine_restart;
> _machine_halt = ltq_machine_halt;
> pm_power_off = ltq_machine_power_off;
> diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c
> index 5764d3ddce69..18725f2d5b67 100644
> --- a/arch/mips/lantiq/xway/sysctrl.c
> +++ b/arch/mips/lantiq/xway/sysctrl.c
> @@ -469,8 +469,8 @@ void __init ltq_soc_init(void)
>
> if (of_machine_is_compatible("lantiq,grx390") ||
> of_machine_is_compatible("lantiq,ar10")) {
> - clkdev_add_pmu("1e101000.usb", "phy", 1, 2, PMU_ANALOG_USB0_P);
> - clkdev_add_pmu("1e106000.usb", "phy", 1, 2, PMU_ANALOG_USB1_P);
> + clkdev_add_pmu("1f203000.rcu:rcu-usb2-phy@0", "phy", 1, 2, PMU_ANALOG_USB0_P);
> + clkdev_add_pmu("1f203000.rcu:rcu-usb2-phy@1", "phy", 1, 2, PMU_ANALOG_USB1_P);
> /* rc 0 */
> clkdev_add_pmu("1d900000.pcie", "phy", 1, 2, PMU_ANALOG_PCIE0_P);
> clkdev_add_pmu("1d900000.pcie", "msi", 1, 1, PMU1_PCIE_MSI);
> @@ -490,8 +490,8 @@ void __init ltq_soc_init(void)
> else
> clkdev_add_static(CLOCK_133M, CLOCK_133M,
> CLOCK_133M, CLOCK_133M);
> - clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0);
> - clkdev_add_pmu("1e101000.usb", "phy", 1, 0, PMU_USB0_P);
> + clkdev_add_pmu("1f203000.rcu:rcu-usb2-phy@0", "ctrl", 1, 0, PMU_USB0);
> + clkdev_add_pmu("1f203000.rcu:rcu-usb2-phy@0", "phy", 1, 0, PMU_USB0_P);
> clkdev_add_pmu("1e180000.etop", "ppe", 1, 0, PMU_PPE);
> clkdev_add_cgu("1e180000.etop", "ephycgu", CGU_EPHY);
> clkdev_add_pmu("1e180000.etop", "ephy", 1, 0, PMU_EPHY);
> @@ -525,10 +525,10 @@ void __init ltq_soc_init(void)
> } else if (of_machine_is_compatible("lantiq,vr9")) {
> clkdev_add_static(ltq_vr9_cpu_hz(), ltq_vr9_fpi_hz(),
> ltq_vr9_fpi_hz(), ltq_vr9_pp32_hz());
> - clkdev_add_pmu("1e101000.usb", "phy", 1, 0, PMU_USB0_P);
> - clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0 | PMU_AHBM);
> - clkdev_add_pmu("1e106000.usb", "phy", 1, 0, PMU_USB1_P);
> - clkdev_add_pmu("1e106000.usb", "ctl", 1, 0, PMU_USB1 | PMU_AHBM);
> + clkdev_add_pmu("1f203000.rcu:rcu-usb2-phy@0", "phy", 1, 0, PMU_USB0_P);
> + clkdev_add_pmu("1f203000.rcu:rcu-usb2-phy@0", "ctrl", 1, 0, PMU_USB0 | PMU_AHBM);
> + clkdev_add_pmu("1f203000.rcu:rcu-usb2-phy@1", "phy", 1, 0, PMU_USB1_P);
> + clkdev_add_pmu("1f203000.rcu:rcu-usb2-phy@1", "ctrl", 1, 0, PMU_USB1 | PMU_AHBM);
> clkdev_add_pmu("1d900000.pcie", "phy", 1, 1, PMU1_PCIE_PHY);
> clkdev_add_pmu("1d900000.pcie", "bus", 1, 0, PMU_PCIE_CLK);
> clkdev_add_pmu("1d900000.pcie", "msi", 1, 1, PMU1_PCIE_MSI);
> @@ -548,8 +548,8 @@ void __init ltq_soc_init(void)
> } else if (of_machine_is_compatible("lantiq,ar9")) {
> clkdev_add_static(ltq_ar9_cpu_hz(), ltq_ar9_fpi_hz(),
> ltq_ar9_fpi_hz(), CLOCK_250M);
> - clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0);
> - clkdev_add_pmu("1e101000.usb", "phy", 1, 0, PMU_USB0_P);
> + clkdev_add_pmu("1f203000.rcu:rcu-usb2-phy@0", "ctrl", 1, 0, PMU_USB0);
> + clkdev_add_pmu("1f203000.rcu:rcu-usb2-phy@0", "phy", 1, 0, PMU_USB0_P);
> clkdev_add_pmu("1e106000.usb", "ctl", 1, 0, PMU_USB1);
> clkdev_add_pmu("1e106000.usb", "phy", 1, 0, PMU_USB1_P);
> clkdev_add_pmu("1e180000.etop", "switch", 1, 0, PMU_SWITCH);
> @@ -560,8 +560,8 @@ void __init ltq_soc_init(void)
> } else {
> clkdev_add_static(ltq_danube_cpu_hz(), ltq_danube_fpi_hz(),
> ltq_danube_fpi_hz(), ltq_danube_pp32_hz());
> - clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0);
> - clkdev_add_pmu("1e101000.usb", "phy", 1, 0, PMU_USB0_P);
> + clkdev_add_pmu("1f203000.rcu:rcu-usb2-phy@0", "ctrl", 1, 0, PMU_USB0);
> + clkdev_add_pmu("1f203000.rcu:rcu-usb2-phy@0", "phy", 1, 0, PMU_USB0_P);
> clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO);
> clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU);
> clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE);
> diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
> index 005cadb7a3f8..dbb450e3ba04 100644
> --- a/drivers/phy/Kconfig
> +++ b/drivers/phy/Kconfig
> @@ -488,6 +488,14 @@ config PHY_CYGNUS_PCIE
> Enable this to support the Broadcom Cygnus PCIe PHY.
> If unsure, say N.
>
> +config PHY_LANTIQ_RCU_USB2
> + tristate "Lantiq XWAY SoC RCU based USB PHY"
> + depends on SOC_TYPE_XWAY
> + depends on OF
> + select GENERIC_PHY
> + help
> + Support for the USB PHY(s) on the Lantiq XWAY family SoCs.
> +
> source "drivers/phy/tegra/Kconfig"
>
> config PHY_NS2_PCIE
> diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
> index dd8f3b5d2918..52631f5ac470 100644
> --- a/drivers/phy/Makefile
> +++ b/drivers/phy/Makefile
> @@ -59,6 +59,7 @@ obj-$(CONFIG_PHY_TUSB1210) += phy-tusb1210.o
> obj-$(CONFIG_PHY_BRCM_SATA) += phy-brcm-sata.o
> obj-$(CONFIG_PHY_PISTACHIO_USB) += phy-pistachio-usb.o
> obj-$(CONFIG_PHY_CYGNUS_PCIE) += phy-bcm-cygnus-pcie.o
> +obj-$(CONFIG_PHY_LANTIQ_RCU_USB2) += phy-lantiq-rcu-usb2.o
> obj-$(CONFIG_ARCH_TEGRA) += tegra/
> obj-$(CONFIG_PHY_NS2_PCIE) += phy-bcm-ns2-pcie.o
> obj-$(CONFIG_PHY_MESON8B_USB2) += phy-meson8b-usb2.o
> diff --git a/drivers/phy/phy-lantiq-rcu-usb2.c b/drivers/phy/phy-lantiq-rcu-usb2.c
> new file mode 100644
> index 000000000000..9bff42afd256
> --- /dev/null
> +++ b/drivers/phy/phy-lantiq-rcu-usb2.c
> @@ -0,0 +1,325 @@
> +/*
> + * Lantiq XWAY SoC RCU module based USB 1.1/2.0 PHY driver
> + *
> + * Copyright (C) 2016 Martin Blumenstingl <martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
> + * Copyright (C) 2017 Hauke Mehrtens <hauke-5/S+JYg5SzeELgA04lAiVw@public.gmane.org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/gpio.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_gpio.h>
> +#include <linux/phy/phy.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/reset.h>
> +
> +#define MAX_VBUS_GPIO 2
> +
> +/* Transmitter HS Pre-Emphasis Enable */
> +#define RCU_CFG1_TX_PEE BIT(0)
> +/* Disconnect Threshold */
> +#define RCU_CFG1_DIS_THR_MASK 0x00038000
> +#define RCU_CFG1_DIS_THR_SHIFT 15
> +
> +struct ltq_rcu_usb2_bits {
> + u8 hostmode;
> + u8 slave_endianness;
> + u8 host_endianness;
> + bool have_ana_cfg;
> +};
> +
> +struct ltq_rcu_usb2_priv {
> + struct regmap *regmap;
> + u32 phy_reg_offset;
> + u32 ana_cfg1_reg_offset;
> + const struct ltq_rcu_usb2_bits *reg_bits;
> + struct device *dev;
> + struct gpio_desc *gpiod_vbus[MAX_VBUS_GPIO];
> + struct phy *phy;
> + struct clk *ctrl_gate_clk;
> + struct clk *phy_gate_clk;
> + struct reset_control *ctrl_reset;
> + struct reset_control *phy_reset;
> +};
> +
> +static const struct ltq_rcu_usb2_bits xway_rcu_usb2_reg_bits = {
> + .hostmode = 11,
> + .slave_endianness = 9,
> + .host_endianness = 10,
> + .have_ana_cfg = false,
> +};
> +
> +static const struct ltq_rcu_usb2_bits xrx100_rcu_usb2_reg_bits = {
> + .hostmode = 11,
> + .slave_endianness = 17,
> + .host_endianness = 10,
> + .have_ana_cfg = false,
> +};
> +
> +static const struct ltq_rcu_usb2_bits xrx200_rcu_usb2_reg_bits = {
> + .hostmode = 11,
> + .slave_endianness = 9,
> + .host_endianness = 10,
> + .have_ana_cfg = true,
> +};
> +
> +static const struct of_device_id ltq_rcu_usb2_phy_of_match[] = {
> + {
> + .compatible = "lantiq,ase-rcu-usb2-phy",
> + .data = &xway_rcu_usb2_reg_bits,
> + },
> + {
> + .compatible = "lantiq,danube-rcu-usb2-phy",
> + .data = &xway_rcu_usb2_reg_bits,
> + },
> + {
> + .compatible = "lantiq,xrx100-rcu-usb2-phy",
> + .data = &xrx100_rcu_usb2_reg_bits,
> + },
> + {
> + .compatible = "lantiq,xrx200-rcu-usb2-phy",
> + .data = &xrx200_rcu_usb2_reg_bits,
> + },
> + {
> + .compatible = "lantiq,xrx300-rcu-usb2-phy",
> + .data = &xrx200_rcu_usb2_reg_bits,
> + },
> + { },
> +};
> +MODULE_DEVICE_TABLE(of, ltq_rcu_usb2_phy_of_match);
> +
> +static void ltq_rcu_usb2_set_vbus_gpio_value(struct gpio_desc **gpiods,
> + int value)
> +{
> + int i;
> +
> + for (i = 0; i < MAX_VBUS_GPIO; i++)
> + if (!IS_ERR_OR_NULL(gpiods[i]))
> + gpiod_set_value(gpiods[i], value);
> +}
> +
> +static int ltq_rcu_usb2_phy_power_on(struct phy *phy)
> +{
> + struct ltq_rcu_usb2_priv *priv = phy_get_drvdata(phy);
> +
> + if (priv->phy_reset)
> + reset_control_deassert(priv->phy_reset);
> +
> + /* enable the port-specific VBUS GPIOs if available */
> + ltq_rcu_usb2_set_vbus_gpio_value(priv->gpiod_vbus, 1);
> +
> + return 0;
> +}
> +
> +static int ltq_rcu_usb2_phy_power_off(struct phy *phy)
> +{
> + struct ltq_rcu_usb2_priv *priv = phy_get_drvdata(phy);
> +
> + /*
> + * only disable the port-specific VBUS GPIO here (if available), the
> + * shared VBUS GPIO might still be used by another port
> + */
> + ltq_rcu_usb2_set_vbus_gpio_value(priv->gpiod_vbus, 0);
> +
> + if (priv->phy_reset)
> + reset_control_assert(priv->phy_reset);
> +
> + return 0;
> +}
> +
> +static struct phy_ops ltq_rcu_usb2_phy_ops = {
> + .power_on = ltq_rcu_usb2_phy_power_on,
> + .power_off = ltq_rcu_usb2_phy_power_off,
> + .owner = THIS_MODULE,
> +};
> +
> +static void ltq_rcu_usb2_start_cores(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct ltq_rcu_usb2_priv *priv = dev_get_drvdata(dev);
> +
> + /* Power on the USB core. */
> + if (clk_prepare_enable(priv->ctrl_gate_clk)) {
> + dev_err(dev, "failed to enable CTRL gate\n");
> + return;
> + }
> +
> + /*
> + * Power on the USB PHY. We have to do it early because
> + * otherwise the second core won't turn on properly.
> + */
> + if (clk_prepare_enable(priv->phy_gate_clk)) {
> + dev_err(dev, "failed to enable PHY gate\n");
> + return;
> + }
> +
> + if (priv->reg_bits->have_ana_cfg) {
> + regmap_update_bits(priv->regmap, priv->ana_cfg1_reg_offset,
> + RCU_CFG1_TX_PEE, RCU_CFG1_TX_PEE);
> + regmap_update_bits(priv->regmap, priv->ana_cfg1_reg_offset,
> + RCU_CFG1_DIS_THR_MASK, 7 << RCU_CFG1_DIS_THR_SHIFT);
> + }
> +
> + /* Configure core to host mode */
> + regmap_update_bits(priv->regmap, priv->phy_reg_offset,
> + BIT(priv->reg_bits->hostmode), 0);
> +
> + /* Select DMA endianness (Host-endian: big-endian) */
> + regmap_update_bits(priv->regmap, priv->phy_reg_offset,
> + BIT(priv->reg_bits->slave_endianness), 0);
> + regmap_update_bits(priv->regmap, priv->phy_reg_offset,
> + BIT(priv->reg_bits->host_endianness),
> + BIT(priv->reg_bits->host_endianness));
> +
> + /* Reset USB core throgh reset controller */
> + reset_control_deassert(priv->ctrl_reset);
> +
> + if (priv->phy_reset)
> + reset_control_assert(priv->phy_reset);
> +}
> +
> +static int ltq_rcu_usb2_get_vbus_gpios(struct device *dev,
> + struct gpio_desc **gpios)
> +{
> + int i;
> +
> + for (i = 0; i < MAX_VBUS_GPIO; i++) {
> + gpios[i] = devm_gpiod_get_index_optional(dev, "vbus", i,
> + GPIOD_OUT_LOW);
> + if (IS_ERR(gpios[i]))
> + return PTR_ERR(gpios[i]);
> + }
> +
> + return 0;
> +}
> +
> +static int ltq_rcu_usb2_of_probe(struct device_node *phynode,
> + struct ltq_rcu_usb2_priv *priv)
> +{
> + struct device *dev = priv->dev;
> + const struct of_device_id *match =
> + of_match_node(ltq_rcu_usb2_phy_of_match, phynode);
> + int ret;
> +
> + if (!match) {
> + dev_err(dev, "Not a compatible Lantiq RCU USB PHY\n");
> + return -EINVAL;
> + }
> +
> + priv->reg_bits = match->data;
> +
> + priv->regmap = syscon_regmap_lookup_by_phandle(phynode,
> + "lantiq,rcu-syscon");
> + if (IS_ERR(priv->regmap)) {
> + dev_err(dev, "Failed to lookup RCU regmap\n");
> + return PTR_ERR(priv->regmap);
> + }
> +
> + ret = ltq_rcu_usb2_get_vbus_gpios(dev, priv->gpiod_vbus);
> + if (ret) {
> + dev_err(dev, "failed to request shared USB VBUS GPIO\n");
> + return ret;
> + }
> +
> + priv->ctrl_gate_clk = devm_clk_get(dev, "ctrl");
> + if (IS_ERR(priv->ctrl_gate_clk)) {
> + dev_err(dev, "Unable to get USB ctrl gate clk\n");
> + return PTR_ERR(priv->ctrl_gate_clk);
> + }
> +
> + priv->phy_gate_clk = devm_clk_get(dev, "phy");
> + if (IS_ERR(priv->phy_gate_clk)) {
> + dev_err(dev, "Unable to get USB phy gate clk\n");
> + return PTR_ERR(priv->phy_gate_clk);
> + }
> +
> + priv->ctrl_reset = devm_reset_control_get_shared(dev, "ctrl");
> + if (IS_ERR(priv->ctrl_reset)) {
> + dev_err(dev, "failed to get 'ctrl' reset\n");
> + return PTR_ERR(priv->ctrl_reset);
> + }
> +
> + priv->phy_reset = devm_reset_control_get_optional(dev, "phy");
> + if (IS_ERR(priv->phy_reset)) {
> + if (PTR_ERR(priv->phy_reset) == -EPROBE_DEFER)
> + return PTR_ERR(priv->phy_reset);
> + priv->phy_reset = NULL;
> + }
> +
> + ret = of_property_read_u32_index(phynode, "lantiq,rcu-syscon", 1,
> + &priv->phy_reg_offset);
> + if (ret) {
> + dev_err(dev, "Failed to get RCU PHY reg offset\n");
> + return ret;
> + }
> +
> + if (priv->reg_bits->have_ana_cfg) {
> + ret = of_property_read_u32_index(phynode, "lantiq,rcu-syscon",
> + 2, &priv->ana_cfg1_reg_offset);
> + if (ret) {
> + dev_dbg(dev, "Failed to get RCU ANA CFG1 reg offset\n");
> + return ret;
> + }
> + }
> +
> + return 0;
> +}
> +
> +static int ltq_rcu_usb2_phy_probe(struct platform_device *pdev)
> +{
> + struct device_node *child, *np = pdev->dev.of_node;
> + struct ltq_rcu_usb2_priv *priv;
> + struct phy_provider *provider;
> + int ret;
> +
> + priv = devm_kzalloc(&pdev->dev, sizeof(*priv),
> + GFP_KERNEL);
> + if (!priv)
> + return -ENOMEM;
> +
> + priv->dev = &pdev->dev;
> + dev_set_drvdata(priv->dev, priv);
> +
> + ret = ltq_rcu_usb2_of_probe(np, priv);
> + if (ret)
> + return ret;
> +
> + priv->phy = devm_phy_create(&pdev->dev, child,
> + <q_rcu_usb2_phy_ops);
> + if (IS_ERR(priv->phy)) {
> + dev_err(&pdev->dev, "failed to create PHY\n");
> + return PTR_ERR(priv->phy);
> + }
> +
> + phy_set_drvdata(priv->phy, priv);
> +
> + ltq_rcu_usb2_start_cores(pdev);
> +
> + provider = devm_of_phy_provider_register(&pdev->dev,
> + of_phy_simple_xlate);
> +
> + return PTR_ERR_OR_ZERO(provider);
> +}
> +
> +static struct platform_driver ltq_rcu_usb2_phy_driver = {
> + .probe = ltq_rcu_usb2_phy_probe,
> + .driver = {
> + .name = "lantiq-rcu-usb2-phy",
> + .of_match_table = ltq_rcu_usb2_phy_of_match,
> + }
> +};
> +module_platform_driver(ltq_rcu_usb2_phy_driver);
> +
> +MODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>");
> +MODULE_DESCRIPTION("Lantiq XWAY USB2 PHY driver");
> +MODULE_LICENSE("GPL v2");
> --
> 2.11.0
>
[0] https://github.com/torvalds/linux/blob/2fbbc4bf69f293df317559a267f4120f290b8fc4/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi#L67
[1] https://github.com/torvalds/linux/blob/2fbbc4bf69f293df317559a267f4120f290b8fc4/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi#L133
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" 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 08/13] reset: Add a reset controller driver for the Lantiq XWAY based SoCs
From: Martin Blumenstingl @ 2017-04-17 21:18 UTC (permalink / raw)
To: Hauke Mehrtens
Cc: ralf-6z/3iImG2C8G8FEW9MqTrA, linux-mips-6z/3iImG2C8G8FEW9MqTrA,
linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-watchdog-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA, john-Pj+rj9U5foFAfugRpC6u6w,
linux-spi-u79uwXL29TY76Z2rM5mHXA,
hauke.mehrtens-ral2JQCrhuEAvxtiuMwx3w
In-Reply-To: <20170417192942.32219-9-hauke-5/S+JYg5SzeELgA04lAiVw@public.gmane.org>
On Mon, Apr 17, 2017 at 9:29 PM, Hauke Mehrtens <hauke-5/S+JYg5SzeELgA04lAiVw@public.gmane.org> wrote:
> From: Martin Blumenstingl <martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
>
> The reset controllers (on xRX200 and newer SoCs have two of them) are
> provided by the RCU module. This was initially implemented as a simple
> reset controller. However, the RCU module provides more functionality
> (ethernet GPHYs, USB PHY, etc.), which makes it a MFD device.
> The old reset controller driver implementation from
> arch/mips/lantiq/xway/reset.c did not honor this fact.
>
> For some devices the request and the status bits are different.
>
> Signed-off-by: Hauke Mehrtens <hauke-5/S+JYg5SzeELgA04lAiVw@public.gmane.org>
I think you should CC the reset controller framework maintainer
(Philipp Zabel <p.zabel-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>) as well
> ---
> .../devicetree/bindings/reset/lantiq,rcu-reset.txt | 43 ++++
> arch/mips/lantiq/xway/reset.c | 68 ------
> drivers/reset/Kconfig | 6 +
> drivers/reset/Makefile | 1 +
> drivers/reset/reset-lantiq-rcu.c | 231 +++++++++++++++++++++
> 5 files changed, 281 insertions(+), 68 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/reset/lantiq,rcu-reset.txt
> create mode 100644 drivers/reset/reset-lantiq-rcu.c
>
> diff --git a/Documentation/devicetree/bindings/reset/lantiq,rcu-reset.txt b/Documentation/devicetree/bindings/reset/lantiq,rcu-reset.txt
> new file mode 100644
> index 000000000000..7f097d16bbb7
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/reset/lantiq,rcu-reset.txt
> @@ -0,0 +1,43 @@
> +Lantiq XWAY SoC RCU reset controller binding
> +============================================
> +
> +This binding describes a reset-controller found on the RCU module on Lantiq
> +XWAY SoCs.
> +
> +
> +-------------------------------------------------------------------------------
> +Required properties (controller (parent) node):
> +- compatible : Should be "lantiq,rcu-reset"
> +- lantiq,rcu-syscon : A phandle to the RCU syscon, the reset register
> + offset and the status register offset.
> +- #reset-cells : Specifies the number of cells needed to encode the
> + reset line, should be 1.
> +
> +Optional properties:
> +- reset-status : The request status bit. For some bits the request bit
> + and the status bit are different. This is depending
> + on the SoC. If the reset-status bit does not match
> + the reset-request bit, put the reset number into the
> + reset-request property and the status bit at the same
> + index into the reset-status property. If no
> + reset-request bit is given here, the driver assume
> + status and request bit are the same.
> +- reset-request : The reset request bit, to map it to the reset-status
> + bit.
> +
> +
> +-------------------------------------------------------------------------------
> +Example for the reset-controllers on the xRX200 SoCs:
> + rcu_reset0: rcu_reset {
> + compatible = "lantiq,rcu-reset";
> + lantiq,rcu-syscon = <&rcu0 0x10 0x14>;
> + #reset-cells = <1>;
> + reset-request = <31>, <29>, <21>, <19>, <16>, <12>;
> + reset-status = <30>, <28>, <16>, <25>, <5>, <24>;
> + };
> +
> + rcu_reset1: rcu_reset {
> + compatible = "lantiq,rcu-reset";
> + lantiq,rcu-syscon = <&rcu0 0x48 0x24>;
> + #reset-cells = <1>;
> + };
> diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c
> index 2dedcf939901..5cb9309b0047 100644
> --- a/arch/mips/lantiq/xway/reset.c
> +++ b/arch/mips/lantiq/xway/reset.c
probably a left-over of my patch: can't this
arch/mips/lantiq/xway/reset.c change go into PATCH #13 as well?
> @@ -194,74 +194,6 @@ int xrx200_gphy_boot(struct device *dev, unsigned int id, dma_addr_t dev_addr)
> return 0;
> }
>
> -/* reset a io domain for u micro seconds */
> -void ltq_reset_once(unsigned int module, ulong u)
> -{
> - ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) | module, RCU_RST_REQ);
> - udelay(u);
> - ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) & ~module, RCU_RST_REQ);
> -}
> -
> -static int ltq_assert_device(struct reset_controller_dev *rcdev,
> - unsigned long id)
> -{
> - u32 val;
> -
> - if (id < 8)
> - return -1;
> -
> - val = ltq_rcu_r32(RCU_RST_REQ);
> - val |= BIT(id);
> - ltq_rcu_w32(val, RCU_RST_REQ);
> -
> - return 0;
> -}
> -
> -static int ltq_deassert_device(struct reset_controller_dev *rcdev,
> - unsigned long id)
> -{
> - u32 val;
> -
> - if (id < 8)
> - return -1;
> -
> - val = ltq_rcu_r32(RCU_RST_REQ);
> - val &= ~BIT(id);
> - ltq_rcu_w32(val, RCU_RST_REQ);
> -
> - return 0;
> -}
> -
> -static int ltq_reset_device(struct reset_controller_dev *rcdev,
> - unsigned long id)
> -{
> - ltq_assert_device(rcdev, id);
> - return ltq_deassert_device(rcdev, id);
> -}
> -
> -static const struct reset_control_ops reset_ops = {
> - .reset = ltq_reset_device,
> - .assert = ltq_assert_device,
> - .deassert = ltq_deassert_device,
> -};
> -
> -static struct reset_controller_dev reset_dev = {
> - .ops = &reset_ops,
> - .owner = THIS_MODULE,
> - .nr_resets = 32,
> - .of_reset_n_cells = 1,
> -};
> -
> -void ltq_rst_init(void)
> -{
> - reset_dev.of_node = of_find_compatible_node(NULL, NULL,
> - "lantiq,xway-reset");
> - if (!reset_dev.of_node)
> - pr_err("Failed to find reset controller node");
> - else
> - reset_controller_register(&reset_dev);
> -}
> -
> static void ltq_machine_restart(char *command)
> {
> u32 val = ltq_rcu_r32(RCU_RST_REQ);
> diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
> index f4cdfe94b9ec..8962ba44248c 100644
> --- a/drivers/reset/Kconfig
> +++ b/drivers/reset/Kconfig
> @@ -27,6 +27,12 @@ config RESET_BERLIN
> help
> This enables the reset controller driver for Marvell Berlin SoCs.
>
> +config RESET_LANTIQ_RCU
> + bool "Lantiq XWAY Reset Driver" if COMPILE_TEST
> + default SOC_TYPE_XWAY
> + help
> + This enables the reset controller driver for Lantiq / Intel XWAY SoCs.
> +
> config RESET_LPC18XX
> bool "LPC18xx/43xx Reset Driver" if COMPILE_TEST
> default ARCH_LPC18XX
> diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
> index 2cd3f6c45165..97b0a844b849 100644
> --- a/drivers/reset/Makefile
> +++ b/drivers/reset/Makefile
> @@ -4,6 +4,7 @@ obj-$(CONFIG_ARCH_STI) += sti/
> obj-$(CONFIG_ARCH_TEGRA) += tegra/
> obj-$(CONFIG_RESET_ATH79) += reset-ath79.o
> obj-$(CONFIG_RESET_BERLIN) += reset-berlin.o
> +obj-$(CONFIG_RESET_LANTIQ_RCU) += reset-lantiq-rcu.o
> obj-$(CONFIG_RESET_LPC18XX) += reset-lpc18xx.o
> obj-$(CONFIG_RESET_MESON) += reset-meson.o
> obj-$(CONFIG_RESET_OXNAS) += reset-oxnas.o
> diff --git a/drivers/reset/reset-lantiq-rcu.c b/drivers/reset/reset-lantiq-rcu.c
> new file mode 100644
> index 000000000000..6178112ca5b4
> --- /dev/null
> +++ b/drivers/reset/reset-lantiq-rcu.c
> @@ -0,0 +1,231 @@
> +/*
> + * 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.
> + *
> + * Copyright (C) 2010 John Crispin <blogic-p3rKhJxN3npAfugRpC6u6w@public.gmane.org>
> + * Copyright (C) 2013-2015 Lantiq Beteiligungs-GmbH & Co.KG
> + * Copyright (C) 2016 Martin Blumenstingl <martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
> + * Copyright (C) 2017 Hauke Mehrtens <hauke-5/S+JYg5SzeELgA04lAiVw@public.gmane.org>
> + */
> +
> +#include <linux/mfd/syscon.h>
> +#include <linux/module.h>
> +#include <linux/regmap.h>
> +#include <linux/reset-controller.h>
> +#include <linux/of_platform.h>
> +
> +#define LANTIQ_RCU_RESET_TIMEOUT 1000000
> +
> +struct lantiq_rcu_reset_translation {
> + int request;
> + int status;
> +};
> +
> +struct lantiq_rcu_reset_priv {
> + struct reset_controller_dev rcdev;
> + struct device *dev;
> + struct regmap *regmap;
> + u32 reset_offset;
> + u32 status_offset;
> + int trans_number;
> + struct lantiq_rcu_reset_translation *trans;
> +};
> +
> +static struct lantiq_rcu_reset_priv *to_lantiq_rcu_reset_priv(
> + struct reset_controller_dev *rcdev)
> +{
> + return container_of(rcdev, struct lantiq_rcu_reset_priv, rcdev);
> +}
> +
> +static int lantiq_rcu_reset_status(struct reset_controller_dev *rcdev,
> + unsigned long id)
> +{
> + struct lantiq_rcu_reset_priv *priv = to_lantiq_rcu_reset_priv(rcdev);
> + u32 val;
> + int ret, i;
> +
> + if (id >= rcdev->nr_resets)
> + return -EINVAL;
> +
> + for (i = 0; i < priv->trans_number; i++) {
> + if (id == priv->trans[i].request) {
> + id = priv->trans[i].status;
> + break;
> + }
> + }
> +
> + ret = regmap_read(priv->regmap, priv->status_offset, &val);
> + if (ret)
> + return ret;
> +
> + return !!(val & BIT(id));
> +}
> +
> +static int lantiq_rcu_reset_update(struct reset_controller_dev *rcdev,
> + unsigned long id, bool assert)
> +{
> + struct lantiq_rcu_reset_priv *priv = to_lantiq_rcu_reset_priv(rcdev);
> + u32 val;
> + int ret, retry = LANTIQ_RCU_RESET_TIMEOUT;
> +
> + if (id >= rcdev->nr_resets)
> + return -EINVAL;
> +
> + if (assert)
> + val = BIT(id);
> + else
> + val = 0;
> +
> + ret = regmap_update_bits(priv->regmap, priv->reset_offset, BIT(id),
> + val);
> + if (ret) {
> + dev_err(priv->dev, "Failed to set reset bit %lu\n", id);
> + return ret;
> + }
> +
> + do {} while (--retry && lantiq_rcu_reset_status(rcdev, id) != assert);
> + if (!retry) {
> + dev_err(priv->dev, "Failed to %s bit %lu\n",
> + assert ? "assert" : "deassert", id);
> + return -EIO;
> + }
> +
> + return 0;
> +}
> +
> +static int lantiq_rcu_reset_assert(struct reset_controller_dev *rcdev,
> + unsigned long id)
> +{
> + return lantiq_rcu_reset_update(rcdev, id, true);
> +}
> +
> +static int lantiq_rcu_reset_deassert(struct reset_controller_dev *rcdev,
> + unsigned long id)
> +{
> + return lantiq_rcu_reset_update(rcdev, id, false);
> +}
> +
> +static int lantiq_rcu_reset_reset(struct reset_controller_dev *rcdev,
> + unsigned long id)
> +{
> + int ret;
> +
> + ret = lantiq_rcu_reset_assert(rcdev, id);
> + if (ret)
> + return ret;
> +
> + return lantiq_rcu_reset_deassert(rcdev, id);
> +}
> +
> +static struct reset_control_ops lantiq_rcu_reset_ops = {
> + .assert = lantiq_rcu_reset_assert,
> + .deassert = lantiq_rcu_reset_deassert,
> + .status = lantiq_rcu_reset_status,
> + .reset = lantiq_rcu_reset_reset,
> +};
> +
> +static int lantiq_rcu_reset_of_probe(struct platform_device *pdev,
> + struct lantiq_rcu_reset_priv *priv)
> +{
> + struct device_node *np = pdev->dev.of_node;
> + int cnt, i, ret;
> +
> + priv->regmap = syscon_regmap_lookup_by_phandle(np,
> + "lantiq,rcu-syscon");
> + if (IS_ERR(priv->regmap)) {
> + dev_err(&pdev->dev, "Failed to lookup RCU regmap\n");
> + return PTR_ERR(priv->regmap);
> + }
> +
> + if (of_property_read_u32_index(np, "lantiq,rcu-syscon", 1,
> + &priv->reset_offset)) {
> + dev_err(&pdev->dev, "Failed to get RCU reset offset\n");
> + return -EINVAL;
> + }
> +
> + if (of_property_read_u32_index(np, "lantiq,rcu-syscon", 2,
> + &priv->status_offset)) {
> + dev_err(&pdev->dev, "Failed to get RCU status offset\n");
> + return -EINVAL;
> + }
> +
> + cnt = of_property_count_elems_of_size(np, "reset-request", sizeof(u32));
> + if (cnt <= 0)
> + return 0;
> +
> + priv->trans = devm_kmalloc_array(&pdev->dev, cnt, sizeof(*priv->trans),
> + GFP_KERNEL);
> + if (!priv->trans)
> + return -ENOMEM;
> +
> + for (i = 0; i < cnt; i++) {
> + ret = of_property_read_u32_index(np, "reset-request", i,
> + &priv->trans[i].request);
> + if (ret) {
> + dev_err(&pdev->dev,
> + "Failed to get reset-request at index %i\n",
> + i);
> + return ret;
> + }
> + ret = of_property_read_u32_index(np, "reset-status", i,
> + &priv->trans[i].status);
> + if (ret) {
> + dev_err(&pdev->dev,
> + "Failed to get reset-status at index %i\n",
> + i);
> + return ret;
> + }
> + }
> + priv->trans_number = cnt;
> +
> + return 0;
> +}
> +
> +static int lantiq_rcu_reset_probe(struct platform_device *pdev)
> +{
> + struct lantiq_rcu_reset_priv *priv;
> + int err;
> +
> + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
> + if (!priv)
> + return -ENOMEM;
> +
> + priv->dev = &pdev->dev;
> + platform_set_drvdata(pdev, priv);
> +
> + err = lantiq_rcu_reset_of_probe(pdev, priv);
> + if (err)
> + return err;
> +
> + priv->rcdev.ops = &lantiq_rcu_reset_ops;
> + priv->rcdev.owner = THIS_MODULE;
> + priv->rcdev.of_node = pdev->dev.of_node;
> + priv->rcdev.of_reset_n_cells = 1;
> + priv->rcdev.nr_resets = 32;
> +
> + err = reset_controller_register(&priv->rcdev);
> + if (err)
> + return err;
> +
> + return 0;
> +}
> +
> +static const struct of_device_id lantiq_rcu_reset_dt_ids[] = {
> + { .compatible = "lantiq,rcu-reset", },
> + { },
> +};
> +MODULE_DEVICE_TABLE(of, lantiq_rcu_reset_dt_ids);
> +
> +static struct platform_driver lantiq_rcu_reset_driver = {
> + .probe = lantiq_rcu_reset_probe,
> + .driver = {
> + .name = "lantiq-rcu-reset",
> + .of_match_table = lantiq_rcu_reset_dt_ids,
> + },
> +};
> +module_platform_driver(lantiq_rcu_reset_driver);
> +
> +MODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>");
> +MODULE_DESCRIPTION("Lantiq XWAY RCU Reset Controller Driver");
> +MODULE_LICENSE("GPL");
> --
> 2.11.0
>
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" 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 00/13] MIPS: lantiq: handle RCU register by separate drivers
From: Martin Blumenstingl @ 2017-04-17 21:14 UTC (permalink / raw)
To: Hauke Mehrtens
Cc: ralf-6z/3iImG2C8G8FEW9MqTrA, linux-mips-6z/3iImG2C8G8FEW9MqTrA,
linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-watchdog-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA, john-Pj+rj9U5foFAfugRpC6u6w,
linux-spi-u79uwXL29TY76Z2rM5mHXA,
hauke.mehrtens-ral2JQCrhuEAvxtiuMwx3w
In-Reply-To: <20170417192942.32219-1-hauke-5/S+JYg5SzeELgA04lAiVw@public.gmane.org>
Hi Hauke,
On Mon, Apr 17, 2017 at 9:29 PM, Hauke Mehrtens <hauke-5/S+JYg5SzeELgA04lAiVw@public.gmane.org> wrote:
> The RCU (Reset controller Unit) register block provides many different
> functionalities. Before they were handed by the code in arch/mips/lantiq
> /xway/reset.c, now there are separate drivers for the functionality.
> This block provides support for reset controller, GPHY firmware
> loading, USB PHY initialization and cross bar configuration.
>
> These changes are making the old device tree incompatible with the
> current kernel. The upstream Linux kernel supports loading the device
> tree blob from the boot loader since about one year, the latest
> released vendor kernel does not support loading the device tree from a
> bot loader.
great to see that you could use my work :-)
> I would prefer if this would go through the mips tree.
> There are more patches planed which would convert the Lantiq code
> to the common clock framework.
>
> Hauke Mehrtens (4):
> mtd: lantiq-flash: drop check of boot select
> mtd: spi-falcon: drop check of boot select
> watchdog: lantiq: access boot cause register through regmap
> MIPS: lantiq: remove old GPHY loader code
>
> Martin Blumenstingl (9):
> MIPS: lantiq: Use of_platform_populate instead of __dt_register_buses
> MIPS: lantiq: Enable MFD_SYSCON to be able to use it for the RCU MFD
> MIPS: lantiq: Convert the xbar driver to a platform_driver
> MIPS: lantiq: remove ltq_reset_cause() and ltq_boot_select()
> reset: Add a reset controller driver for the Lantiq XWAY based SoCs
> MIPS: lantiq: Add a GPHY driver which uses the RCU syscon-mfd
> phy: Add an USB PHY driver for the Lantiq SoCs using the RCU module
> Documentation: DT: MIPS: lantiq: Add docs for the RCU bindings
> MIPS: lantiq: Remove the arch/mips/lantiq/xway/reset.c implementation
if anyone is wondering:
I started porting the lantiq target to the common clock framework
"some" time ago. unfortunately it turned out that some of the
"drivers" are tightly coupled and one cannot simply port the clock
handling to the common clock framework. so I started tackling more
drivers in arch/mips/lantiq/ until I had a huge pile of patches in my
tree but no time to improve them so they were ready to submit. so the
patches from Hauke are roughly based on the ideas of my patches (and
probably a few lines of code here and there).
> .../devicetree/bindings/mips/lantiq/rcu-gphy.txt | 54 +++
> .../devicetree/bindings/mips/lantiq/rcu.txt | 82 +++++
> .../devicetree/bindings/mips/lantiq/xbar.txt | 22 ++
> .../bindings/phy/phy-lantiq-rcu-usb2.txt | 59 ++++
> .../devicetree/bindings/reset/lantiq,rcu-reset.txt | 43 +++
> MAINTAINERS | 1 +
> arch/mips/include/asm/mach-lantiq/lantiq.h | 4 -
> arch/mips/lantiq/Kconfig | 2 +
> arch/mips/lantiq/falcon/reset.c | 22 --
> arch/mips/lantiq/prom.c | 3 +-
> arch/mips/lantiq/xway/Makefile | 4 +-
> arch/mips/lantiq/xway/reset.c | 387 ---------------------
> arch/mips/lantiq/xway/sysctrl.c | 69 +---
> arch/mips/lantiq/xway/xrx200_phy_fw.c | 113 ------
> drivers/mtd/maps/lantiq-flash.c | 6 -
> drivers/phy/Kconfig | 8 +
> drivers/phy/Makefile | 1 +
> drivers/phy/phy-lantiq-rcu-usb2.c | 325 +++++++++++++++++
> drivers/reset/Kconfig | 6 +
> drivers/reset/Makefile | 1 +
> drivers/reset/reset-lantiq-rcu.c | 231 ++++++++++++
> drivers/soc/Makefile | 1 +
> drivers/soc/lantiq/Makefile | 2 +
> drivers/soc/lantiq/gphy.c | 242 +++++++++++++
> drivers/soc/lantiq/xbar.c | 100 ++++++
> drivers/spi/spi-falcon.c | 5 -
> drivers/watchdog/lantiq_wdt.c | 47 ++-
> include/dt-bindings/mips/lantiq_rcu_gphy.h | 15 +
> 28 files changed, 1255 insertions(+), 600 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/mips/lantiq/rcu-gphy.txt
> create mode 100644 Documentation/devicetree/bindings/mips/lantiq/rcu.txt
> create mode 100644 Documentation/devicetree/bindings/mips/lantiq/xbar.txt
> create mode 100644 Documentation/devicetree/bindings/phy/phy-lantiq-rcu-usb2.txt
> create mode 100644 Documentation/devicetree/bindings/reset/lantiq,rcu-reset.txt
> delete mode 100644 arch/mips/lantiq/xway/reset.c
> delete mode 100644 arch/mips/lantiq/xway/xrx200_phy_fw.c
> create mode 100644 drivers/phy/phy-lantiq-rcu-usb2.c
> create mode 100644 drivers/reset/reset-lantiq-rcu.c
> create mode 100644 drivers/soc/lantiq/Makefile
> create mode 100644 drivers/soc/lantiq/gphy.c
> create mode 100644 drivers/soc/lantiq/xbar.c
> create mode 100644 include/dt-bindings/mips/lantiq_rcu_gphy.h
>
> --
> 2.11.0
>
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" 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 v3 3/4] bluetooth: hci_uart: add LL protocol serdev driver support
From: Adam Ford @ 2017-04-17 20:11 UTC (permalink / raw)
To: Rob Herring
Cc: Marcel Holtmann, linux-bluetooth-u79uwXL29TY76Z2rM5mHXA,
Mark Rutland, devicetree-u79uwXL29TY76Z2rM5mHXA, Johan Hedberg,
Gustavo Padovan, Satish Patel, Wei Xu, Eyal Reizer,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20170413150353.7389-4-robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
On Thu, Apr 13, 2017 at 10:03 AM, Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
> Turns out that the LL protocol and the TI-ST are the same thing AFAICT.
> The TI-ST adds firmware loading, GPIO control, and shared access for
> NFC, FM radio, etc. For now, we're only implementing what is needed for
> BT. This mirrors other drivers like BCM and Intel, but uses the new
> serdev bus.
>
> The firmware loading is greatly simplified by using existing
> infrastructure to send commands. It may be a bit slower than the
> original code using synchronous functions, but the real bottleneck is
> likely doing firmware load at 115.2kbps.
I am using pdata-quirks to drive my wl1283 Bluetooth on a DM3730. I
have the Bluetooth set to 3000000 baud in pdata quirks. Looking at
the binding, I don't see an option to set the baudrate. Is there (or
will there) be a way to set the baud rate of the Bluetooth?
adam
>
> Signed-off-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> Cc: Marcel Holtmann <marcel-kz+m5ild9QBg9hUCZPvPmw@public.gmane.org>
> Cc: Gustavo Padovan <gustavo-THi1TnShQwVAfugRpC6u6w@public.gmane.org>
> Cc: Johan Hedberg <johan.hedberg-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> Cc: linux-bluetooth-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> ---
> v3:
> - rebase on bluetooth-next
> - Add explicit of.h include
> v2:
> - Use IS_ENABLED() to fix module build
>
> drivers/bluetooth/hci_ll.c | 262 ++++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 261 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/bluetooth/hci_ll.c b/drivers/bluetooth/hci_ll.c
> index 02692fe30279..485e8eb04542 100644
> --- a/drivers/bluetooth/hci_ll.c
> +++ b/drivers/bluetooth/hci_ll.c
> @@ -34,20 +34,24 @@
> #include <linux/sched.h>
> #include <linux/types.h>
> #include <linux/fcntl.h>
> +#include <linux/firmware.h>
> #include <linux/interrupt.h>
> #include <linux/ptrace.h>
> #include <linux/poll.h>
>
> #include <linux/slab.h>
> -#include <linux/tty.h>
> #include <linux/errno.h>
> #include <linux/string.h>
> #include <linux/signal.h>
> #include <linux/ioctl.h>
> +#include <linux/of.h>
> +#include <linux/serdev.h>
> #include <linux/skbuff.h>
> +#include <linux/ti_wilink_st.h>
>
> #include <net/bluetooth/bluetooth.h>
> #include <net/bluetooth/hci_core.h>
> +#include <linux/gpio/consumer.h>
>
> #include "hci_uart.h"
>
> @@ -76,6 +80,12 @@ struct hcill_cmd {
> u8 cmd;
> } __packed;
>
> +struct ll_device {
> + struct hci_uart hu;
> + struct serdev_device *serdev;
> + struct gpio_desc *enable_gpio;
> +};
> +
> struct ll_struct {
> unsigned long rx_state;
> unsigned long rx_count;
> @@ -136,6 +146,9 @@ static int ll_open(struct hci_uart *hu)
>
> hu->priv = ll;
>
> + if (hu->serdev)
> + serdev_device_open(hu->serdev);
> +
> return 0;
> }
>
> @@ -164,6 +177,13 @@ static int ll_close(struct hci_uart *hu)
>
> kfree_skb(ll->rx_skb);
>
> + if (hu->serdev) {
> + struct ll_device *lldev = serdev_device_get_drvdata(hu->serdev);
> + gpiod_set_value_cansleep(lldev->enable_gpio, 0);
> +
> + serdev_device_close(hu->serdev);
> + }
> +
> hu->priv = NULL;
>
> kfree(ll);
> @@ -505,9 +525,245 @@ static struct sk_buff *ll_dequeue(struct hci_uart *hu)
> return skb_dequeue(&ll->txq);
> }
>
> +#if IS_ENABLED(CONFIG_SERIAL_DEV_BUS)
> +static int read_local_version(struct hci_dev *hdev)
> +{
> + int err = 0;
> + unsigned short version = 0;
> + struct sk_buff *skb;
> + struct hci_rp_read_local_version *ver;
> +
> + skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL, HCI_INIT_TIMEOUT);
> + if (IS_ERR(skb)) {
> + bt_dev_err(hdev, "Reading TI version information failed (%ld)",
> + PTR_ERR(skb));
> + err = PTR_ERR(skb);
> + goto out;
> + }
> + if (skb->len != sizeof(*ver)) {
> + err = -EILSEQ;
> + goto out;
> + }
> +
> + ver = (struct hci_rp_read_local_version *)skb->data;
> + if (le16_to_cpu(ver->manufacturer) != 13) {
> + err = -ENODEV;
> + goto out;
> + }
> +
> + version = le16_to_cpu(ver->lmp_subver);
> +
> +out:
> + if (err) bt_dev_err(hdev, "Failed to read TI version info: %d", err);
> + kfree_skb(skb);
> + return err ? err : version;
> +}
> +
> +/**
> + * download_firmware -
> + * internal function which parses through the .bts firmware
> + * script file intreprets SEND, DELAY actions only as of now
> + */
> +static int download_firmware(struct ll_device *lldev)
> +{
> + unsigned short chip, min_ver, maj_ver;
> + int version, err, len;
> + unsigned char *ptr, *action_ptr;
> + unsigned char bts_scr_name[40]; /* 40 char long bts scr name? */
> + const struct firmware *fw;
> + struct sk_buff *skb;
> + struct hci_command *cmd;
> +
> + version = read_local_version(lldev->hu.hdev);
> + if (version < 0)
> + return version;
> +
> + chip = (version & 0x7C00) >> 10;
> + min_ver = (version & 0x007F);
> + maj_ver = (version & 0x0380) >> 7;
> + if (version & 0x8000)
> + maj_ver |= 0x0008;
> +
> + snprintf(bts_scr_name, sizeof(bts_scr_name),
> + "ti-connectivity/TIInit_%d.%d.%d.bts",
> + chip, maj_ver, min_ver);
> +
> + err = request_firmware(&fw, bts_scr_name, &lldev->serdev->dev);
> + if (err || !fw->data || !fw->size) {
> + bt_dev_err(lldev->hu.hdev, "request_firmware failed(errno %d) for %s",
> + err, bts_scr_name);
> + return -EINVAL;
> + }
> + ptr = (void *)fw->data;
> + len = fw->size;
> + /* bts_header to remove out magic number and
> + * version
> + */
> + ptr += sizeof(struct bts_header);
> + len -= sizeof(struct bts_header);
> +
> + while (len > 0 && ptr) {
> + bt_dev_dbg(lldev->hu.hdev, " action size %d, type %d ",
> + ((struct bts_action *)ptr)->size,
> + ((struct bts_action *)ptr)->type);
> +
> + action_ptr = &(((struct bts_action *)ptr)->data[0]);
> +
> + switch (((struct bts_action *)ptr)->type) {
> + case ACTION_SEND_COMMAND: /* action send */
> + bt_dev_dbg(lldev->hu.hdev, "S");
> + cmd = (struct hci_command *)action_ptr;
> + if (cmd->opcode == 0xff36) {
> + /* ignore remote change
> + * baud rate HCI VS command */
> + bt_dev_warn(lldev->hu.hdev, "change remote baud rate command in firmware");
> + break;
> + }
> + if (cmd->prefix != 1)
> + bt_dev_dbg(lldev->hu.hdev, "command type %d\n", cmd->prefix);
> +
> + skb = __hci_cmd_sync(lldev->hu.hdev, cmd->opcode, cmd->plen, &cmd->speed, HCI_INIT_TIMEOUT);
> + if (IS_ERR(skb)) {
> + bt_dev_err(lldev->hu.hdev, "send command failed\n");
> + goto out_rel_fw;
> + }
> + kfree_skb(skb);
> + break;
> + case ACTION_WAIT_EVENT: /* wait */
> + /* no need to wait as command was synchronous */
> + bt_dev_dbg(lldev->hu.hdev, "W");
> + break;
> + case ACTION_DELAY: /* sleep */
> + bt_dev_info(lldev->hu.hdev, "sleep command in scr");
> + mdelay(((struct bts_action_delay *)action_ptr)->msec);
> + break;
> + }
> + len -= (sizeof(struct bts_action) +
> + ((struct bts_action *)ptr)->size);
> + ptr += sizeof(struct bts_action) +
> + ((struct bts_action *)ptr)->size;
> + }
> +
> +out_rel_fw:
> + /* fw download complete */
> + release_firmware(fw);
> + return err;
> +}
> +
> +static int ll_setup(struct hci_uart *hu)
> +{
> + int err, retry = 3;
> + struct ll_device *lldev;
> + struct serdev_device *serdev = hu->serdev;
> + u32 speed;
> +
> + if (!serdev)
> + return 0;
> +
> + lldev = serdev_device_get_drvdata(serdev);
> +
> + serdev_device_set_flow_control(serdev, true);
> +
> + do {
> + /* Configure BT_EN to HIGH state */
> + gpiod_set_value_cansleep(lldev->enable_gpio, 0);
> + msleep(5);
> + gpiod_set_value_cansleep(lldev->enable_gpio, 1);
> + msleep(100);
> +
> + err = download_firmware(lldev);
> + if (!err)
> + break;
> +
> + /* Toggle BT_EN and retry */
> + bt_dev_err(hu->hdev, "download firmware failed, retrying...");
> + } while (retry--);
> +
> + if (err)
> + return err;
> +
> + /* Operational speed if any */
> + if (hu->oper_speed)
> + speed = hu->oper_speed;
> + else if (hu->proto->oper_speed)
> + speed = hu->proto->oper_speed;
> + else
> + speed = 0;
> +
> + if (speed) {
> + struct sk_buff *skb = __hci_cmd_sync(hu->hdev, 0xff36, sizeof(speed), &speed, HCI_INIT_TIMEOUT);
> + if (!IS_ERR(skb)) {
> + kfree_skb(skb);
> + serdev_device_set_baudrate(serdev, speed);
> + }
> + }
> +
> + return 0;
> +}
> +
> +static const struct hci_uart_proto llp;
> +
> +static int hci_ti_probe(struct serdev_device *serdev)
> +{
> + struct hci_uart *hu;
> + struct ll_device *lldev;
> + u32 max_speed = 3000000;
> +
> + lldev = devm_kzalloc(&serdev->dev, sizeof(struct ll_device), GFP_KERNEL);
> + if (!lldev)
> + return -ENOMEM;
> + hu = &lldev->hu;
> +
> + serdev_device_set_drvdata(serdev, lldev);
> + lldev->serdev = hu->serdev = serdev;
> +
> + lldev->enable_gpio = devm_gpiod_get_optional(&serdev->dev, "enable", GPIOD_OUT_LOW);
> + if (IS_ERR(lldev->enable_gpio))
> + return PTR_ERR(lldev->enable_gpio);
> +
> + of_property_read_u32(serdev->dev.of_node, "max-speed", &max_speed);
> + hci_uart_set_speeds(hu, 115200, max_speed);
> +
> + return hci_uart_register_device(hu, &llp);
> +}
> +
> +static void hci_ti_remove(struct serdev_device *serdev)
> +{
> + struct ll_device *lldev = serdev_device_get_drvdata(serdev);
> + struct hci_uart *hu = &lldev->hu;
> + struct hci_dev *hdev = hu->hdev;
> +
> + cancel_work_sync(&hu->write_work);
> +
> + hci_unregister_dev(hdev);
> + hci_free_dev(hdev);
> + hu->proto->close(hu);
> +}
> +
> +static const struct of_device_id hci_ti_of_match[] = {
> + { .compatible = "ti,wl1831-st" },
> + { .compatible = "ti,wl1835-st" },
> + { .compatible = "ti,wl1837-st" },
> + {},
> +};
> +MODULE_DEVICE_TABLE(of, hci_ti_of_match);
> +
> +static struct serdev_device_driver hci_ti_drv = {
> + .driver = {
> + .name = "hci-ti",
> + .of_match_table = of_match_ptr(hci_ti_of_match),
> + },
> + .probe = hci_ti_probe,
> + .remove = hci_ti_remove,
> +};
> +#else
> +#define ll_setup NULL
> +#endif
> +
> static const struct hci_uart_proto llp = {
> .id = HCI_UART_LL,
> .name = "LL",
> + .setup = ll_setup,
> .open = ll_open,
> .close = ll_close,
> .recv = ll_recv,
> @@ -518,10 +774,14 @@ static const struct hci_uart_proto llp = {
>
> int __init ll_init(void)
> {
> + serdev_device_driver_register(&hci_ti_drv);
> +
> return hci_uart_register_proto(&llp);
> }
>
> int __exit ll_deinit(void)
> {
> + serdev_device_driver_unregister(&hci_ti_drv);
> +
> return hci_uart_unregister_proto(&llp);
> }
> --
> 2.11.0
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
--
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 V5 2/2] thermal: broadcom: add Northstar thermal driver
From: Stefan Wahren @ 2017-04-17 20:09 UTC (permalink / raw)
To: Rafał Miłecki, Rafał Miłecki,
Eduardo Valentin
Cc: Mark Rutland, devicetree, Florian Fainelli, Scott Branden,
linux-pm, Ray Jui, Lee Jones, Jon Mason, Rob Herring,
bcm-kernel-feedback-list, linux-rpi-kernel, Zhang Rui,
linux-arm-kernel
In-Reply-To: <6dd2617d-a8a8-d7a4-53a4-7ebcb274573c@milecki.pl>
> Rafał Miłecki <rafal@milecki.pl> hat am 14. April 2017 um 14:16 geschrieben:
>
>
> On 04/07/2017 06:42 AM, Eduardo Valentin wrote:
> > On Mon, Apr 03, 2017 at 05:48:29PM +0200, Rafał Miłecki wrote:
> >> From: Rafał Miłecki <rafal@milecki.pl>
> >>
> >> Northstar is a SoC family commonly used in home routers. This commit
> >> adds a driver for checking CPU temperature. As Northstar Plus seems to
> >> also have this IP block this new symbol gets ARCH_BCM_IPROC dependency.
> >>
> >> Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
> >> Signed-off-by: Jon Mason <jon.mason@broadcom.com>
> >
> > If no objection, I am applying this series.
>
> Cool, hopefully there aren't any more objections :) Once applied should I
> expect this in
> https://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux-soc-thermal.git/log/?h=next
> ?
>
> That would allow me to move bcm2835_thermal.c to the broadcom subdir.
Thanks for doing this. Btw Northstar thermal driver misses a MODULE_AUTHOR.
Regards
Stefan
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH V5 3/3] mtd: physmap_of: drop duplicated support for linux, part-probe property
From: Rafał Miłecki @ 2017-04-17 19:47 UTC (permalink / raw)
To: David Woodhouse, Brian Norris, Boris Brezillon, Marek Vasut,
Richard Weinberger, Cyrille Pitchen
Cc: Rob Herring, Mark Rutland, Frank Rowand, Linus Walleij,
linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA, Rafał Miłecki
In-Reply-To: <20170417194746.10697-1-zajec5-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
From: Rafał Miłecki <rafal-g1n6cQUeyibVItvQsEIGlw@public.gmane.org>
Now support for linux,part-probe has been added to the MTD core there is
no need to duplicate support for it in physmap_of.
Signed-off-by: Rafał Miłecki <rafal-g1n6cQUeyibVItvQsEIGlw@public.gmane.org>
Acked-by: Boris Brezillon <boris.brezillon-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
---
drivers/mtd/maps/physmap_of.c | 46 +------------------------------------------
1 file changed, 1 insertion(+), 45 deletions(-)
diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c
index 14e8909c9955..49dbb7235848 100644
--- a/drivers/mtd/maps/physmap_of.c
+++ b/drivers/mtd/maps/physmap_of.c
@@ -114,47 +114,9 @@ static struct mtd_info *obsolete_probe(struct platform_device *dev,
static const char * const part_probe_types_def[] = {
"cmdlinepart", "RedBoot", "ofpart", "ofoldpart", NULL };
-static const char * const *of_get_probes(struct device_node *dp)
-{
- const char *cp;
- int cplen;
- unsigned int l;
- unsigned int count;
- const char **res;
-
- cp = of_get_property(dp, "linux,part-probe", &cplen);
- if (cp == NULL)
- return part_probe_types_def;
-
- count = 0;
- for (l = 0; l != cplen; l++)
- if (cp[l] == 0)
- count++;
-
- res = kzalloc((count + 1)*sizeof(*res), GFP_KERNEL);
- if (!res)
- return NULL;
- count = 0;
- while (cplen > 0) {
- res[count] = cp;
- l = strlen(cp) + 1;
- cp += l;
- cplen -= l;
- count++;
- }
- return res;
-}
-
-static void of_free_probes(const char * const *probes)
-{
- if (probes != part_probe_types_def)
- kfree(probes);
-}
-
static const struct of_device_id of_flash_match[];
static int of_flash_probe(struct platform_device *dev)
{
- const char * const *part_probe_types;
const struct of_device_id *match;
struct device_node *dp = dev->dev.of_node;
struct resource res;
@@ -320,14 +282,8 @@ static int of_flash_probe(struct platform_device *dev)
info->cmtd->dev.parent = &dev->dev;
mtd_set_of_node(info->cmtd, dp);
- part_probe_types = of_get_probes(dp);
- if (!part_probe_types) {
- err = -ENOMEM;
- goto err_out;
- }
- mtd_device_parse_register(info->cmtd, part_probe_types, NULL,
+ mtd_device_parse_register(info->cmtd, part_probe_types_def, NULL,
NULL, 0);
- of_free_probes(part_probe_types);
kfree(mtd_list);
--
2.11.0
--
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 V5 2/3] mtd: add core code reading DT specified part probes
From: Rafał Miłecki @ 2017-04-17 19:47 UTC (permalink / raw)
To: David Woodhouse, Brian Norris, Boris Brezillon, Marek Vasut,
Richard Weinberger, Cyrille Pitchen
Cc: Rob Herring, Mark Rutland, Frank Rowand, Linus Walleij,
linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA, Rafał Miłecki
In-Reply-To: <20170417194746.10697-1-zajec5-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
From: Rafał Miłecki <rafal-g1n6cQUeyibVItvQsEIGlw@public.gmane.org>
Handling (creating) partitions for flash devices requires using a proper
driver that will read partition table (out of somewhere). We can't
simply try all existing drivers one by one:
1) It would increase boot time
2) The order could be a problem
3) In some corner cases parsers could misinterpret some data as a table
Due to this MTD subsystem allows drivers to specify a list of applicable
part probes.
So far physmap_of was the only driver with support for linux,part-probe
DT property. Other ones had list or probes hardcoded which wasn't making
them really flexible. It prevented using common flash drivers on
platforms that required some specific partition table access.
This commit adds support for mentioned DT property directly to the MTD
core. It's a rewritten implementation of physmap_of's code and it makes
original code obsolete. Thanks to calling it on device parse
registration (as suggested by Boris) all drivers gain support for it for
free.
Signed-off-by: Rafał Miłecki <rafal-g1n6cQUeyibVItvQsEIGlw@public.gmane.org>
Acked-by: Boris Brezillon <boris.brezillon-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
---
V4: Rename of functions
Add comment to the of_get_mtd_part_probes
Simplify mtd_device_parse_register changes
Thanks Boris for help on all above!
V5: Rename variable to of_part_probe_types
---
drivers/mtd/mtdcore.c | 34 ++++++++++++++++++++++++++++++++++
1 file changed, 34 insertions(+)
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 66a9dedd1062..228bcfd03cf0 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -664,6 +664,33 @@ static void mtd_set_dev_defaults(struct mtd_info *mtd)
}
}
+static const char * const *of_get_mtd_part_probes(struct device_node *np)
+{
+ const char **res;
+ int count;
+
+ count = of_property_count_strings(np, "linux,part-probe");
+ if (count < 0)
+ return NULL;
+
+ /* This looks common: consider helper function if copying */
+ res = kzalloc((count + 1) * sizeof(*res), GFP_KERNEL);
+ if (!res)
+ return NULL;
+
+ count = of_property_read_string_array(np, "linux,part-probe", res,
+ count);
+ if (count < 0)
+ return NULL;
+
+ return res;
+}
+
+static void of_free_mtd_part_probes(const char * const *probes)
+{
+ kfree(probes);
+}
+
/**
* mtd_device_parse_register - parse partitions and register an MTD device.
*
@@ -698,11 +725,16 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types,
const struct mtd_partition *parts,
int nr_parts)
{
+ const char * const *of_part_probe_types;
struct mtd_partitions parsed;
int ret;
mtd_set_dev_defaults(mtd);
+ of_part_probe_types = of_get_mtd_part_probes(mtd_get_of_node(mtd));
+ if (of_part_probe_types)
+ types = of_part_probe_types;
+
memset(&parsed, 0, sizeof(parsed));
ret = parse_mtd_partitions(mtd, types, &parsed, parser_data);
@@ -720,6 +752,8 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types,
memset(&parsed, 0, sizeof(parsed));
}
+ of_free_mtd_part_probes(of_part_probe_types);
+
ret = mtd_add_device_partitions(mtd, &parsed);
if (ret)
goto out;
--
2.11.0
--
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 V5 1/3] dt-bindings: mtd: document linux,part-probe property
From: Rafał Miłecki @ 2017-04-17 19:47 UTC (permalink / raw)
To: David Woodhouse, Brian Norris, Boris Brezillon, Marek Vasut,
Richard Weinberger, Cyrille Pitchen
Cc: Rob Herring, Mark Rutland, Frank Rowand, Linus Walleij,
linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA, Rafał Miłecki
In-Reply-To: <20170417182853.24281-1-zajec5-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
From: Rafał Miłecki <rafal-g1n6cQUeyibVItvQsEIGlw@public.gmane.org>
Support for this property has been introduced in 2010 with commit
9d5da3a9b849 ("mtd: extend physmap_of to let the device tree specify the
parition probe") but it was never documented. Fix this by adding a
proper description and example.
Signed-off-by: Rafał Miłecki <rafal-g1n6cQUeyibVItvQsEIGlw@public.gmane.org>
Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Acked-by: Boris Brezillon <boris.brezillon-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
---
Documentation/devicetree/bindings/mtd/common.txt | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/Documentation/devicetree/bindings/mtd/common.txt b/Documentation/devicetree/bindings/mtd/common.txt
index fc068b923d7a..1ada70e718b2 100644
--- a/Documentation/devicetree/bindings/mtd/common.txt
+++ b/Documentation/devicetree/bindings/mtd/common.txt
@@ -6,10 +6,17 @@ Optional properties:
controller based name) in order to ease flash device identification
and/or describe what they are used for.
+- linux,part-probe: if present, this property should contain a list of strings
+ with partition probes to be used for the flash device. A role of partition
+ probe (parser) is to read/construct partition table and register found
+ partitions. Getting partition table may be platform or device specific so
+ various devices may use various Linux drivers for this purpose.
+
Example:
flash@0 {
label = "System-firmware";
+ linux,part-probe = "cmdlinepart", "ofpart";
/* flash type specific properties */
};
--
2.11.0
--
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] ARM: dts: BCM5301X: Add CPU thermal sensor and zone
From: Jon Mason @ 2017-04-17 19:39 UTC (permalink / raw)
To: Rafał Miłecki
Cc: Florian Fainelli, Hauke Mehrtens, Rob Herring, Mark Rutland,
Russell King, linux-arm-kernel, BCM Kernel Feedback,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
Rafał Miłecki
In-Reply-To: <CACna6rwR__iyPO6NcO3STtKz+aXfNiZFsNXhYwTHs27pTrrU9Q-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Mon, Apr 17, 2017 at 12:14 PM, Rafał Miłecki <zajec5-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> On 17 April 2017 at 16:54, Jon Mason <jon.mason-dY08KVG/lbpWk0Htik3J/w@public.gmane.org> wrote:
>> On Fri, Apr 14, 2017 at 5:42 PM, Rafał Miłecki <zajec5@gmail.com> wrote:
>>> From: Rafał Miłecki <rafal-g1n6cQUeyibVItvQsEIGlw@public.gmane.org>
>>>
>>> This uses CPU thermal sensor available on every Northstar chipset to
>>> monitor temperature. We don't have any cooling or throttling so only a
>>> critical trip was added.
>>
>> Haha! You beat me to it (as I had a similar patch queued).
>>
>> This looks good to me.
>>
>> Acked-by: Jon Mason <jon.mason-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>
>
> :) Thanks
>
> I'd appreciate adding thermal to NSP DT. I don't have any NSP unit to
> try it on my own.
I'm doing so right now. I have it working, I just need to clean up the patches.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH V4 2/3] mtd: add core code reading DT specified part probes
From: Boris Brezillon @ 2017-04-17 19:31 UTC (permalink / raw)
To: Rafał Miłecki
Cc: David Woodhouse, Brian Norris, Marek Vasut, Richard Weinberger,
Cyrille Pitchen, Rob Herring, Mark Rutland, Frank Rowand,
Linus Walleij, linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA, Rafał Miłecki
In-Reply-To: <20170417182853.24281-2-zajec5-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
On Mon, 17 Apr 2017 20:28:52 +0200
Rafał Miłecki <zajec5-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> From: Rafał Miłecki <rafal-g1n6cQUeyibVItvQsEIGlw@public.gmane.org>
>
> Handling (creating) partitions for flash devices requires using a proper
> driver that will read partition table (out of somewhere). We can't
> simply try all existing drivers one by one:
> 1) It would increase boot time
> 2) The order could be a problem
> 3) In some corner cases parsers could misinterpret some data as a table
> Due to this MTD subsystem allows drivers to specify a list of applicable
> part probes.
>
> So far physmap_of was the only driver with support for linux,part-probe
> DT property. Other ones had list or probes hardcoded which wasn't making
> them really flexible. It prevented using common flash drivers on
> platforms that required some specific partition table access.
>
> This commit adds support for mentioned DT property directly to the MTD
> core. It's a rewritten implementation of physmap_of's code and it makes
> original code obsolete. Thanks to calling it on device parse
> registration (as suggested by Boris) all drivers gain support for it for
> free.
>
> Signed-off-by: Rafał Miłecki <rafal-g1n6cQUeyibVItvQsEIGlw@public.gmane.org>
> ---
> V4: Rename of functions
> Add comment to the of_get_mtd_part_probes
> Simplify mtd_device_parse_register changes
> Thanks Boris for help on all above!
> ---
> drivers/mtd/mtdcore.c | 34 ++++++++++++++++++++++++++++++++++
> 1 file changed, 34 insertions(+)
>
> diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
> index 66a9dedd1062..07b07de7e080 100644
> --- a/drivers/mtd/mtdcore.c
> +++ b/drivers/mtd/mtdcore.c
> @@ -664,6 +664,33 @@ static void mtd_set_dev_defaults(struct mtd_info *mtd)
> }
> }
>
> +static const char * const *of_get_mtd_part_probes(struct device_node *np)
> +{
> + const char **res;
> + int count;
> +
> + count = of_property_count_strings(np, "linux,part-probe");
> + if (count < 0)
> + return NULL;
> +
> + /* This looks common: consider helper function if copying */
> + res = kzalloc((count + 1) * sizeof(*res), GFP_KERNEL);
> + if (!res)
> + return NULL;
> +
> + count = of_property_read_string_array(np, "linux,part-probe", res,
> + count);
> + if (count < 0)
> + return NULL;
> +
> + return res;
> +}
> +
> +static void of_free_mtd_part_probes(const char * const *probes)
> +{
> + kfree(probes);
> +}
> +
> /**
> * mtd_device_parse_register - parse partitions and register an MTD device.
> *
> @@ -698,11 +725,16 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types,
> const struct mtd_partition *parts,
> int nr_parts)
> {
> + const char * const *part_probe_types;
One last thing: can we rename this variable of_part_probe_types?
With this addressed,
Acked-by: Boris Brezillon <boris.brezillon-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
Thanks,
Boris
> struct mtd_partitions parsed;
> int ret;
>
> mtd_set_dev_defaults(mtd);
>
> + part_probe_types = of_get_mtd_part_probes(mtd_get_of_node(mtd));
> + if (part_probe_types)
> + types = part_probe_types;
> +
> memset(&parsed, 0, sizeof(parsed));
>
> ret = parse_mtd_partitions(mtd, types, &parsed, parser_data);
> @@ -720,6 +752,8 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types,
> memset(&parsed, 0, sizeof(parsed));
> }
>
> + of_free_mtd_part_probes(part_probe_types);
> +
> ret = mtd_add_device_partitions(mtd, &parsed);
> if (ret)
> goto out;
--
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
* [PATCH 13/13] MIPS: lantiq: Remove the arch/mips/lantiq/xway/reset.c implementation
From: Hauke Mehrtens @ 2017-04-17 19:29 UTC (permalink / raw)
To: ralf-6z/3iImG2C8G8FEW9MqTrA
Cc: linux-mips-6z/3iImG2C8G8FEW9MqTrA,
linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-watchdog-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg,
john-Pj+rj9U5foFAfugRpC6u6w, linux-spi-u79uwXL29TY76Z2rM5mHXA,
hauke.mehrtens-ral2JQCrhuEAvxtiuMwx3w, Hauke Mehrtens
In-Reply-To: <20170417192942.32219-1-hauke-5/S+JYg5SzeELgA04lAiVw@public.gmane.org>
From: Martin Blumenstingl <martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
The RCU register are now access through separates drivers. remove the
last peaces of the old implementation.
Signed-off-by: Hauke Mehrtens <hauke-5/S+JYg5SzeELgA04lAiVw@public.gmane.org>
---
arch/mips/lantiq/Kconfig | 1 +
arch/mips/lantiq/xway/Makefile | 2 +-
arch/mips/lantiq/xway/reset.c | 157 -----------------------------------------
3 files changed, 2 insertions(+), 158 deletions(-)
delete mode 100644 arch/mips/lantiq/xway/reset.c
diff --git a/arch/mips/lantiq/Kconfig b/arch/mips/lantiq/Kconfig
index f5db4a426568..35bc69b78268 100644
--- a/arch/mips/lantiq/Kconfig
+++ b/arch/mips/lantiq/Kconfig
@@ -18,6 +18,7 @@ config SOC_XWAY
select SOC_TYPE_XWAY
select HW_HAS_PCI
select MFD_SYSCON
+ select MFD_CORE
config SOC_FALCON
bool "FALCON"
diff --git a/arch/mips/lantiq/xway/Makefile b/arch/mips/lantiq/xway/Makefile
index 6daf3149e7ca..fbb0747c70b7 100644
--- a/arch/mips/lantiq/xway/Makefile
+++ b/arch/mips/lantiq/xway/Makefile
@@ -1,3 +1,3 @@
-obj-y := prom.o sysctrl.o clk.o reset.o dma.o gptu.o dcdc.o
+obj-y := prom.o sysctrl.o clk.o dma.o gptu.o dcdc.o
obj-y += vmmc.o
diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c
deleted file mode 100644
index 5aec1f54275b..000000000000
--- a/arch/mips/lantiq/xway/reset.c
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * 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.
- *
- * Copyright (C) 2010 John Crispin <john-Pj+rj9U5foFAfugRpC6u6w@public.gmane.org>
- * Copyright (C) 2013-2015 Lantiq Beteiligungs-GmbH & Co.KG
- */
-
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/ioport.h>
-#include <linux/pm.h>
-#include <linux/export.h>
-#include <linux/delay.h>
-#include <linux/of_address.h>
-#include <linux/of_platform.h>
-#include <linux/reset-controller.h>
-
-#include <asm/reboot.h>
-
-#include <lantiq_soc.h>
-
-#include "../prom.h"
-
-/* reset request register */
-#define RCU_RST_REQ 0x0010
-/* reset status register */
-#define RCU_RST_STAT 0x0014
-
-/* xbar BE flag */
-#define RCU_AHB_ENDIAN 0x004C
-#define RCU_VR9_BE_AHB1S 0x00000008
-
-/* reboot bit */
-#define RCU_RD_GPHY0_XRX200 BIT(31)
-#define RCU_RD_SRST BIT(30)
-#define RCU_RD_GPHY1_XRX200 BIT(29)
-
-/* reset cause */
-#define RCU_STAT_SHIFT 26
-/* boot selection */
-#define RCU_BOOT_SEL(x) ((x >> 18) & 0x7)
-#define RCU_BOOT_SEL_XRX200(x) (((x >> 17) & 0xf) | ((x >> 8) & 0x10))
-
-/* dwc2 USB configuration registers */
-#define RCU_USB1CFG 0x0018
-#define RCU_USB2CFG 0x0034
-
-/* USB DMA endianness bits */
-#define RCU_USBCFG_HDSEL_BIT BIT(11)
-#define RCU_USBCFG_HOST_END_BIT BIT(10)
-#define RCU_USBCFG_SLV_END_BIT BIT(9)
-
-/* USB reset bits */
-#define RCU_USBRESET 0x0010
-
-#define USBRESET_BIT BIT(4)
-
-#define RCU_USBRESET2 0x0048
-
-#define USB1RESET_BIT BIT(4)
-#define USB2RESET_BIT BIT(5)
-
-#define RCU_CFG1A 0x0038
-#define RCU_CFG1B 0x003C
-
-/* USB PMU devices */
-#define PMU_AHBM BIT(15)
-#define PMU_USB0 BIT(6)
-#define PMU_USB1 BIT(27)
-
-/* USB PHY PMU devices */
-#define PMU_USB0_P BIT(0)
-#define PMU_USB1_P BIT(26)
-
-/* remapped base addr of the reset control unit */
-static void __iomem *ltq_rcu_membase;
-static struct device_node *ltq_rcu_np;
-static DEFINE_SPINLOCK(ltq_rcu_lock);
-
-static void ltq_rcu_w32(uint32_t val, uint32_t reg_off)
-{
- ltq_w32(val, ltq_rcu_membase + reg_off);
-}
-
-static uint32_t ltq_rcu_r32(uint32_t reg_off)
-{
- return ltq_r32(ltq_rcu_membase + reg_off);
-}
-
-static void ltq_rcu_w32_mask(uint32_t clr, uint32_t set, uint32_t reg_off)
-{
- unsigned long flags;
-
- spin_lock_irqsave(<q_rcu_lock, flags);
- ltq_rcu_w32((ltq_rcu_r32(reg_off) & ~(clr)) | (set), reg_off);
- spin_unlock_irqrestore(<q_rcu_lock, flags);
-}
-
-static void ltq_machine_restart(char *command)
-{
- u32 val = ltq_rcu_r32(RCU_RST_REQ);
-
- if (of_device_is_compatible(ltq_rcu_np, "lantiq,rcu-xrx200"))
- val |= RCU_RD_GPHY1_XRX200 | RCU_RD_GPHY0_XRX200;
-
- val |= RCU_RD_SRST;
-
- local_irq_disable();
- ltq_rcu_w32(val, RCU_RST_REQ);
- unreachable();
-}
-
-static void ltq_machine_halt(void)
-{
- local_irq_disable();
- unreachable();
-}
-
-static void ltq_machine_power_off(void)
-{
- local_irq_disable();
- unreachable();
-}
-
-static int __init mips_reboot_setup(void)
-{
- struct resource res;
-
- ltq_rcu_np = of_find_compatible_node(NULL, NULL, "lantiq,rcu-xway");
- if (!ltq_rcu_np)
- ltq_rcu_np = of_find_compatible_node(NULL, NULL,
- "lantiq,rcu-xrx200");
-
- /* check if all the reset register range is available */
- if (!ltq_rcu_np)
- panic("Failed to load reset resources from devicetree");
-
- if (of_address_to_resource(ltq_rcu_np, 0, &res))
- panic("Failed to get rcu memory range");
-
- if (!request_mem_region(res.start, resource_size(&res), res.name))
- pr_err("Failed to request rcu memory");
-
- ltq_rcu_membase = ioremap_nocache(res.start, resource_size(&res));
- if (!ltq_rcu_membase)
- panic("Failed to remap core memory");
-
- _machine_restart = ltq_machine_restart;
- _machine_halt = ltq_machine_halt;
- pm_power_off = ltq_machine_power_off;
-
- return 0;
-}
-
-arch_initcall(mips_reboot_setup);
--
2.11.0
--
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 12/13] Documentation: DT: MIPS: lantiq: Add docs for the RCU bindings
From: Hauke Mehrtens @ 2017-04-17 19:29 UTC (permalink / raw)
To: ralf-6z/3iImG2C8G8FEW9MqTrA
Cc: linux-mips-6z/3iImG2C8G8FEW9MqTrA,
linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-watchdog-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg,
john-Pj+rj9U5foFAfugRpC6u6w, linux-spi-u79uwXL29TY76Z2rM5mHXA,
hauke.mehrtens-ral2JQCrhuEAvxtiuMwx3w, Hauke Mehrtens
In-Reply-To: <20170417192942.32219-1-hauke-5/S+JYg5SzeELgA04lAiVw@public.gmane.org>
From: Martin Blumenstingl <martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
This adds the initial documentation for the RCU module (a MFD device
which provides USB PHYs, reset controllers and more).
Signed-off-by: Hauke Mehrtens <hauke-5/S+JYg5SzeELgA04lAiVw@public.gmane.org>
---
.../devicetree/bindings/mips/lantiq/rcu.txt | 82 ++++++++++++++++++++++
1 file changed, 82 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mips/lantiq/rcu.txt
diff --git a/Documentation/devicetree/bindings/mips/lantiq/rcu.txt b/Documentation/devicetree/bindings/mips/lantiq/rcu.txt
new file mode 100644
index 000000000000..9e5b1e7493e4
--- /dev/null
+++ b/Documentation/devicetree/bindings/mips/lantiq/rcu.txt
@@ -0,0 +1,82 @@
+Lantiq XWAY SoC RCU binding
+===========================
+
+This binding describes the RCU (reset controller unit) multifunction device,
+where each sub-device has it's own set of registers.
+
+
+-------------------------------------------------------------------------------
+Required properties:
+- compatible : The first and second values must be: "simple-mfd", "syscon"
+- reg : The address and length of the system control registers
+
+
+-------------------------------------------------------------------------------
+Example of the RCU bindings on a xRX200 SoC:
+ rcu0: rcu@203000 {
+ compatible = "simple-mfd", "syscon";
+ reg = <0x203000 0x100>;
+ big-endian;
+
+ gphy0: rcu_gphy@0 {
+ compatible = "lantiq,xrx200a2x-rcu-gphy";
+ lantiq,rcu-syscon = <&rcu0 0x20>;
+ resets = <&rcu_reset0 31>;
+ reset-names = "gphy";
+ lantiq,gphy-mode = <GPHY_MODE_GE>;
+ clocks = <&pmu0 XRX200_PMU_GATE_GPHY>;
+ clock-names = "gphy";
+ };
+
+ gphy1: rcu_gphy@1 {
+ compatible = "lantiq,xrx200a2x-rcu-gphy";
+ lantiq,rcu-syscon = <&rcu0 0x68>;
+ resets = <&rcu_reset0 29>;
+ reset-names = "gphy";
+ lantiq,gphy-mode = <GPHY_MODE_FE>;
+ clocks = <&pmu0 XRX200_PMU_GATE_GPHY>;
+ clock-names = "gphy";
+ };
+
+ rcu_reset0: rcu_reset@0 {
+ compatible = "lantiq,rcu-reset";
+ lantiq,rcu-syscon = <&rcu0 0x10 0x14>;
+ #reset-cells = <1>;
+ reset-request = <31>, <29>, <21>, <19>, <16>, <12>;
+ reset-status = <30>, <28>, <16>, <25>, <5>, <24>;
+ };
+
+ rcu_reset1: rcu_reset@1 {
+ compatible = "lantiq,rcu-reset";
+ lantiq,rcu-syscon = <&rcu0 0x48 0x24>;
+ #reset-cells = <1>;
+ };
+
+ usb_phys0: rcu-usb2-phy@0 {
+ compatible = "lantiq,xrx200-rcu-usb2-phy";
+
+ lantiq,rcu-syscon = <&rcu0 0x18 0x38>;
+ resets = <&rcu_reset1 4>, <&rcu_reset0 4>;
+ reset-names = "phy", "ctrl";
+ #phy-cells = <0>;
+ };
+
+ usb_phys1: rcu-usb2-phy@1 {
+ compatible = "lantiq,xrx200-rcu-usb2-phy";
+
+ lantiq,rcu-syscon = <&rcu0 0x34 0x3C>;
+ resets = <&rcu_reset1 5>, <&rcu_reset0 4>;
+ reset-names = "phy", "ctrl";
+ #phy-cells = <0>;
+ };
+
+ reboot {
+ compatible = "syscon-reboot";
+ regmap = <&rcu0>;
+ offset = <0x10>;
+ mask = <0x40000000>;
+ };
+
+ /* more sub-device nodes (USB PHY, etc.) */
+ };
+
--
2.11.0
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" 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 11/13] phy: Add an USB PHY driver for the Lantiq SoCs using the RCU module
From: Hauke Mehrtens @ 2017-04-17 19:29 UTC (permalink / raw)
To: ralf-6z/3iImG2C8G8FEW9MqTrA
Cc: linux-mips-6z/3iImG2C8G8FEW9MqTrA,
linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-watchdog-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg,
john-Pj+rj9U5foFAfugRpC6u6w, linux-spi-u79uwXL29TY76Z2rM5mHXA,
hauke.mehrtens-ral2JQCrhuEAvxtiuMwx3w, Hauke Mehrtens
In-Reply-To: <20170417192942.32219-1-hauke-5/S+JYg5SzeELgA04lAiVw@public.gmane.org>
From: Martin Blumenstingl <martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
This driver starts the DWC2 core(s) built into the XWAY SoCs and provides
the PHY interfaces for each core. The phy instances can be passed to the
dwc2 driver, which already supports the generic phy interface.
Signed-off-by: Hauke Mehrtens <hauke-5/S+JYg5SzeELgA04lAiVw@public.gmane.org>
---
.../bindings/phy/phy-lantiq-rcu-usb2.txt | 59 ++++
arch/mips/lantiq/xway/reset.c | 43 ---
arch/mips/lantiq/xway/sysctrl.c | 24 +-
drivers/phy/Kconfig | 8 +
drivers/phy/Makefile | 1 +
drivers/phy/phy-lantiq-rcu-usb2.c | 325 +++++++++++++++++++++
6 files changed, 405 insertions(+), 55 deletions(-)
create mode 100644 Documentation/devicetree/bindings/phy/phy-lantiq-rcu-usb2.txt
create mode 100644 drivers/phy/phy-lantiq-rcu-usb2.c
diff --git a/Documentation/devicetree/bindings/phy/phy-lantiq-rcu-usb2.txt b/Documentation/devicetree/bindings/phy/phy-lantiq-rcu-usb2.txt
new file mode 100644
index 000000000000..0ec9f790b6e0
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/phy-lantiq-rcu-usb2.txt
@@ -0,0 +1,59 @@
+Lantiq XWAY SoC RCU USB 1.1/2.0 PHY binding
+===========================================
+
+This binding describes the USB PHY hardware provided by the RCU module on the
+Lantiq XWAY SoCs.
+
+
+-------------------------------------------------------------------------------
+Required properties (controller (parent) node):
+- compatible : Should be one of
+ "lantiq,ase-rcu-usb2-phy"
+ "lantiq,danube-rcu-usb2-phy"
+ "lantiq,xrx100-rcu-usb2-phy"
+ "lantiq,xrx200-rcu-usb2-phy"
+ "lantiq,xrx300-rcu-usb2-phy"
+- lantiq,rcu-syscon : A phandle to the RCU module and the offsets to the
+ USB PHY configuration and USB MAC registers.
+- address-cells : should be 1
+- size-cells : should be 0
+- phy-cells : from the generic PHY bindings, must be 1
+
+Optional properties (controller (parent) node):
+- vbus-gpio : References a GPIO which enables VBUS all given USB
+ ports.
+
+Required nodes : A sub-node is required for each USB PHY port.
+
+
+-------------------------------------------------------------------------------
+Required properties (port (child) node):
+- reg : The ID of the USB port, usually 0 or 1.
+- clocks : References to the (PMU) "ctrl" and "phy" clk gates.
+- clock-names : Must be one of the following:
+ "ctrl"
+ "phy"
+- resets : References to the RCU USB configuration reset bits.
+- reset-names : Must be one of the following:
+ "analog-config" (optional)
+ "statemachine-soft" (optional)
+
+Optional properties (port (child) node):
+- vbus-gpio : References a GPIO which enables VBUS for the USB port.
+
+
+-------------------------------------------------------------------------------
+Example for the USB PHYs on an xRX200 SoC:
+ usb_phys0: rcu-usb2-phy@0 {
+ compatible = "lantiq,xrx200-rcu-usb2-phy";
+ reg = <0>;
+
+ lantiq,rcu-syscon = <&rcu0 0x18 0x38>;
+ clocks = <&pmu PMU_GATE_USB0_CTRL>,
+ <&pmu PMU_GATE_USB0_PHY>;
+ clock-names = "ctrl", "phy";
+ vbus-gpios = <&gpio 32 GPIO_ACTIVE_HIGH>;
+ resets = <&rcu_reset1 4>, <&rcu_reset0 4>;
+ reset-names = "phy", "ctrl";
+ #phy-cells = <0>;
+ };
diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c
index 3f30fb81a50f..5aec1f54275b 100644
--- a/arch/mips/lantiq/xway/reset.c
+++ b/arch/mips/lantiq/xway/reset.c
@@ -124,45 +124,6 @@ static void ltq_machine_power_off(void)
unreachable();
}
-static void ltq_usb_init(void)
-{
- /* Power for USB cores 1 & 2 */
- ltq_pmu_enable(PMU_AHBM);
- ltq_pmu_enable(PMU_USB0);
- ltq_pmu_enable(PMU_USB1);
-
- ltq_rcu_w32(ltq_rcu_r32(RCU_CFG1A) | BIT(0), RCU_CFG1A);
- ltq_rcu_w32(ltq_rcu_r32(RCU_CFG1B) | BIT(0), RCU_CFG1B);
-
- /* Enable USB PHY power for cores 1 & 2 */
- ltq_pmu_enable(PMU_USB0_P);
- ltq_pmu_enable(PMU_USB1_P);
-
- /* Configure cores to host mode */
- ltq_rcu_w32(ltq_rcu_r32(RCU_USB1CFG) & ~RCU_USBCFG_HDSEL_BIT,
- RCU_USB1CFG);
- ltq_rcu_w32(ltq_rcu_r32(RCU_USB2CFG) & ~RCU_USBCFG_HDSEL_BIT,
- RCU_USB2CFG);
-
- /* Select DMA endianness (Host-endian: big-endian) */
- ltq_rcu_w32((ltq_rcu_r32(RCU_USB1CFG) & ~RCU_USBCFG_SLV_END_BIT)
- | RCU_USBCFG_HOST_END_BIT, RCU_USB1CFG);
- ltq_rcu_w32(ltq_rcu_r32((RCU_USB2CFG) & ~RCU_USBCFG_SLV_END_BIT)
- | RCU_USBCFG_HOST_END_BIT, RCU_USB2CFG);
-
- /* Hard reset USB state machines */
- ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET) | USBRESET_BIT, RCU_USBRESET);
- udelay(50 * 1000);
- ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET) & ~USBRESET_BIT, RCU_USBRESET);
-
- /* Soft reset USB state machines */
- ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET2)
- | USB1RESET_BIT | USB2RESET_BIT, RCU_USBRESET2);
- udelay(50 * 1000);
- ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET2)
- & ~(USB1RESET_BIT | USB2RESET_BIT), RCU_USBRESET2);
-}
-
static int __init mips_reboot_setup(void)
{
struct resource res;
@@ -186,10 +147,6 @@ static int __init mips_reboot_setup(void)
if (!ltq_rcu_membase)
panic("Failed to remap core memory");
- if (of_machine_is_compatible("lantiq,ar9") ||
- of_machine_is_compatible("lantiq,vr9"))
- ltq_usb_init();
-
_machine_restart = ltq_machine_restart;
_machine_halt = ltq_machine_halt;
pm_power_off = ltq_machine_power_off;
diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c
index 5764d3ddce69..18725f2d5b67 100644
--- a/arch/mips/lantiq/xway/sysctrl.c
+++ b/arch/mips/lantiq/xway/sysctrl.c
@@ -469,8 +469,8 @@ void __init ltq_soc_init(void)
if (of_machine_is_compatible("lantiq,grx390") ||
of_machine_is_compatible("lantiq,ar10")) {
- clkdev_add_pmu("1e101000.usb", "phy", 1, 2, PMU_ANALOG_USB0_P);
- clkdev_add_pmu("1e106000.usb", "phy", 1, 2, PMU_ANALOG_USB1_P);
+ clkdev_add_pmu("1f203000.rcu:rcu-usb2-phy@0", "phy", 1, 2, PMU_ANALOG_USB0_P);
+ clkdev_add_pmu("1f203000.rcu:rcu-usb2-phy@1", "phy", 1, 2, PMU_ANALOG_USB1_P);
/* rc 0 */
clkdev_add_pmu("1d900000.pcie", "phy", 1, 2, PMU_ANALOG_PCIE0_P);
clkdev_add_pmu("1d900000.pcie", "msi", 1, 1, PMU1_PCIE_MSI);
@@ -490,8 +490,8 @@ void __init ltq_soc_init(void)
else
clkdev_add_static(CLOCK_133M, CLOCK_133M,
CLOCK_133M, CLOCK_133M);
- clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0);
- clkdev_add_pmu("1e101000.usb", "phy", 1, 0, PMU_USB0_P);
+ clkdev_add_pmu("1f203000.rcu:rcu-usb2-phy@0", "ctrl", 1, 0, PMU_USB0);
+ clkdev_add_pmu("1f203000.rcu:rcu-usb2-phy@0", "phy", 1, 0, PMU_USB0_P);
clkdev_add_pmu("1e180000.etop", "ppe", 1, 0, PMU_PPE);
clkdev_add_cgu("1e180000.etop", "ephycgu", CGU_EPHY);
clkdev_add_pmu("1e180000.etop", "ephy", 1, 0, PMU_EPHY);
@@ -525,10 +525,10 @@ void __init ltq_soc_init(void)
} else if (of_machine_is_compatible("lantiq,vr9")) {
clkdev_add_static(ltq_vr9_cpu_hz(), ltq_vr9_fpi_hz(),
ltq_vr9_fpi_hz(), ltq_vr9_pp32_hz());
- clkdev_add_pmu("1e101000.usb", "phy", 1, 0, PMU_USB0_P);
- clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0 | PMU_AHBM);
- clkdev_add_pmu("1e106000.usb", "phy", 1, 0, PMU_USB1_P);
- clkdev_add_pmu("1e106000.usb", "ctl", 1, 0, PMU_USB1 | PMU_AHBM);
+ clkdev_add_pmu("1f203000.rcu:rcu-usb2-phy@0", "phy", 1, 0, PMU_USB0_P);
+ clkdev_add_pmu("1f203000.rcu:rcu-usb2-phy@0", "ctrl", 1, 0, PMU_USB0 | PMU_AHBM);
+ clkdev_add_pmu("1f203000.rcu:rcu-usb2-phy@1", "phy", 1, 0, PMU_USB1_P);
+ clkdev_add_pmu("1f203000.rcu:rcu-usb2-phy@1", "ctrl", 1, 0, PMU_USB1 | PMU_AHBM);
clkdev_add_pmu("1d900000.pcie", "phy", 1, 1, PMU1_PCIE_PHY);
clkdev_add_pmu("1d900000.pcie", "bus", 1, 0, PMU_PCIE_CLK);
clkdev_add_pmu("1d900000.pcie", "msi", 1, 1, PMU1_PCIE_MSI);
@@ -548,8 +548,8 @@ void __init ltq_soc_init(void)
} else if (of_machine_is_compatible("lantiq,ar9")) {
clkdev_add_static(ltq_ar9_cpu_hz(), ltq_ar9_fpi_hz(),
ltq_ar9_fpi_hz(), CLOCK_250M);
- clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0);
- clkdev_add_pmu("1e101000.usb", "phy", 1, 0, PMU_USB0_P);
+ clkdev_add_pmu("1f203000.rcu:rcu-usb2-phy@0", "ctrl", 1, 0, PMU_USB0);
+ clkdev_add_pmu("1f203000.rcu:rcu-usb2-phy@0", "phy", 1, 0, PMU_USB0_P);
clkdev_add_pmu("1e106000.usb", "ctl", 1, 0, PMU_USB1);
clkdev_add_pmu("1e106000.usb", "phy", 1, 0, PMU_USB1_P);
clkdev_add_pmu("1e180000.etop", "switch", 1, 0, PMU_SWITCH);
@@ -560,8 +560,8 @@ void __init ltq_soc_init(void)
} else {
clkdev_add_static(ltq_danube_cpu_hz(), ltq_danube_fpi_hz(),
ltq_danube_fpi_hz(), ltq_danube_pp32_hz());
- clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0);
- clkdev_add_pmu("1e101000.usb", "phy", 1, 0, PMU_USB0_P);
+ clkdev_add_pmu("1f203000.rcu:rcu-usb2-phy@0", "ctrl", 1, 0, PMU_USB0);
+ clkdev_add_pmu("1f203000.rcu:rcu-usb2-phy@0", "phy", 1, 0, PMU_USB0_P);
clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO);
clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU);
clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE);
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 005cadb7a3f8..dbb450e3ba04 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -488,6 +488,14 @@ config PHY_CYGNUS_PCIE
Enable this to support the Broadcom Cygnus PCIe PHY.
If unsure, say N.
+config PHY_LANTIQ_RCU_USB2
+ tristate "Lantiq XWAY SoC RCU based USB PHY"
+ depends on SOC_TYPE_XWAY
+ depends on OF
+ select GENERIC_PHY
+ help
+ Support for the USB PHY(s) on the Lantiq XWAY family SoCs.
+
source "drivers/phy/tegra/Kconfig"
config PHY_NS2_PCIE
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index dd8f3b5d2918..52631f5ac470 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -59,6 +59,7 @@ obj-$(CONFIG_PHY_TUSB1210) += phy-tusb1210.o
obj-$(CONFIG_PHY_BRCM_SATA) += phy-brcm-sata.o
obj-$(CONFIG_PHY_PISTACHIO_USB) += phy-pistachio-usb.o
obj-$(CONFIG_PHY_CYGNUS_PCIE) += phy-bcm-cygnus-pcie.o
+obj-$(CONFIG_PHY_LANTIQ_RCU_USB2) += phy-lantiq-rcu-usb2.o
obj-$(CONFIG_ARCH_TEGRA) += tegra/
obj-$(CONFIG_PHY_NS2_PCIE) += phy-bcm-ns2-pcie.o
obj-$(CONFIG_PHY_MESON8B_USB2) += phy-meson8b-usb2.o
diff --git a/drivers/phy/phy-lantiq-rcu-usb2.c b/drivers/phy/phy-lantiq-rcu-usb2.c
new file mode 100644
index 000000000000..9bff42afd256
--- /dev/null
+++ b/drivers/phy/phy-lantiq-rcu-usb2.c
@@ -0,0 +1,325 @@
+/*
+ * Lantiq XWAY SoC RCU module based USB 1.1/2.0 PHY driver
+ *
+ * Copyright (C) 2016 Martin Blumenstingl <martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
+ * Copyright (C) 2017 Hauke Mehrtens <hauke-5/S+JYg5SzeELgA04lAiVw@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_gpio.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+
+#define MAX_VBUS_GPIO 2
+
+/* Transmitter HS Pre-Emphasis Enable */
+#define RCU_CFG1_TX_PEE BIT(0)
+/* Disconnect Threshold */
+#define RCU_CFG1_DIS_THR_MASK 0x00038000
+#define RCU_CFG1_DIS_THR_SHIFT 15
+
+struct ltq_rcu_usb2_bits {
+ u8 hostmode;
+ u8 slave_endianness;
+ u8 host_endianness;
+ bool have_ana_cfg;
+};
+
+struct ltq_rcu_usb2_priv {
+ struct regmap *regmap;
+ u32 phy_reg_offset;
+ u32 ana_cfg1_reg_offset;
+ const struct ltq_rcu_usb2_bits *reg_bits;
+ struct device *dev;
+ struct gpio_desc *gpiod_vbus[MAX_VBUS_GPIO];
+ struct phy *phy;
+ struct clk *ctrl_gate_clk;
+ struct clk *phy_gate_clk;
+ struct reset_control *ctrl_reset;
+ struct reset_control *phy_reset;
+};
+
+static const struct ltq_rcu_usb2_bits xway_rcu_usb2_reg_bits = {
+ .hostmode = 11,
+ .slave_endianness = 9,
+ .host_endianness = 10,
+ .have_ana_cfg = false,
+};
+
+static const struct ltq_rcu_usb2_bits xrx100_rcu_usb2_reg_bits = {
+ .hostmode = 11,
+ .slave_endianness = 17,
+ .host_endianness = 10,
+ .have_ana_cfg = false,
+};
+
+static const struct ltq_rcu_usb2_bits xrx200_rcu_usb2_reg_bits = {
+ .hostmode = 11,
+ .slave_endianness = 9,
+ .host_endianness = 10,
+ .have_ana_cfg = true,
+};
+
+static const struct of_device_id ltq_rcu_usb2_phy_of_match[] = {
+ {
+ .compatible = "lantiq,ase-rcu-usb2-phy",
+ .data = &xway_rcu_usb2_reg_bits,
+ },
+ {
+ .compatible = "lantiq,danube-rcu-usb2-phy",
+ .data = &xway_rcu_usb2_reg_bits,
+ },
+ {
+ .compatible = "lantiq,xrx100-rcu-usb2-phy",
+ .data = &xrx100_rcu_usb2_reg_bits,
+ },
+ {
+ .compatible = "lantiq,xrx200-rcu-usb2-phy",
+ .data = &xrx200_rcu_usb2_reg_bits,
+ },
+ {
+ .compatible = "lantiq,xrx300-rcu-usb2-phy",
+ .data = &xrx200_rcu_usb2_reg_bits,
+ },
+ { },
+};
+MODULE_DEVICE_TABLE(of, ltq_rcu_usb2_phy_of_match);
+
+static void ltq_rcu_usb2_set_vbus_gpio_value(struct gpio_desc **gpiods,
+ int value)
+{
+ int i;
+
+ for (i = 0; i < MAX_VBUS_GPIO; i++)
+ if (!IS_ERR_OR_NULL(gpiods[i]))
+ gpiod_set_value(gpiods[i], value);
+}
+
+static int ltq_rcu_usb2_phy_power_on(struct phy *phy)
+{
+ struct ltq_rcu_usb2_priv *priv = phy_get_drvdata(phy);
+
+ if (priv->phy_reset)
+ reset_control_deassert(priv->phy_reset);
+
+ /* enable the port-specific VBUS GPIOs if available */
+ ltq_rcu_usb2_set_vbus_gpio_value(priv->gpiod_vbus, 1);
+
+ return 0;
+}
+
+static int ltq_rcu_usb2_phy_power_off(struct phy *phy)
+{
+ struct ltq_rcu_usb2_priv *priv = phy_get_drvdata(phy);
+
+ /*
+ * only disable the port-specific VBUS GPIO here (if available), the
+ * shared VBUS GPIO might still be used by another port
+ */
+ ltq_rcu_usb2_set_vbus_gpio_value(priv->gpiod_vbus, 0);
+
+ if (priv->phy_reset)
+ reset_control_assert(priv->phy_reset);
+
+ return 0;
+}
+
+static struct phy_ops ltq_rcu_usb2_phy_ops = {
+ .power_on = ltq_rcu_usb2_phy_power_on,
+ .power_off = ltq_rcu_usb2_phy_power_off,
+ .owner = THIS_MODULE,
+};
+
+static void ltq_rcu_usb2_start_cores(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct ltq_rcu_usb2_priv *priv = dev_get_drvdata(dev);
+
+ /* Power on the USB core. */
+ if (clk_prepare_enable(priv->ctrl_gate_clk)) {
+ dev_err(dev, "failed to enable CTRL gate\n");
+ return;
+ }
+
+ /*
+ * Power on the USB PHY. We have to do it early because
+ * otherwise the second core won't turn on properly.
+ */
+ if (clk_prepare_enable(priv->phy_gate_clk)) {
+ dev_err(dev, "failed to enable PHY gate\n");
+ return;
+ }
+
+ if (priv->reg_bits->have_ana_cfg) {
+ regmap_update_bits(priv->regmap, priv->ana_cfg1_reg_offset,
+ RCU_CFG1_TX_PEE, RCU_CFG1_TX_PEE);
+ regmap_update_bits(priv->regmap, priv->ana_cfg1_reg_offset,
+ RCU_CFG1_DIS_THR_MASK, 7 << RCU_CFG1_DIS_THR_SHIFT);
+ }
+
+ /* Configure core to host mode */
+ regmap_update_bits(priv->regmap, priv->phy_reg_offset,
+ BIT(priv->reg_bits->hostmode), 0);
+
+ /* Select DMA endianness (Host-endian: big-endian) */
+ regmap_update_bits(priv->regmap, priv->phy_reg_offset,
+ BIT(priv->reg_bits->slave_endianness), 0);
+ regmap_update_bits(priv->regmap, priv->phy_reg_offset,
+ BIT(priv->reg_bits->host_endianness),
+ BIT(priv->reg_bits->host_endianness));
+
+ /* Reset USB core throgh reset controller */
+ reset_control_deassert(priv->ctrl_reset);
+
+ if (priv->phy_reset)
+ reset_control_assert(priv->phy_reset);
+}
+
+static int ltq_rcu_usb2_get_vbus_gpios(struct device *dev,
+ struct gpio_desc **gpios)
+{
+ int i;
+
+ for (i = 0; i < MAX_VBUS_GPIO; i++) {
+ gpios[i] = devm_gpiod_get_index_optional(dev, "vbus", i,
+ GPIOD_OUT_LOW);
+ if (IS_ERR(gpios[i]))
+ return PTR_ERR(gpios[i]);
+ }
+
+ return 0;
+}
+
+static int ltq_rcu_usb2_of_probe(struct device_node *phynode,
+ struct ltq_rcu_usb2_priv *priv)
+{
+ struct device *dev = priv->dev;
+ const struct of_device_id *match =
+ of_match_node(ltq_rcu_usb2_phy_of_match, phynode);
+ int ret;
+
+ if (!match) {
+ dev_err(dev, "Not a compatible Lantiq RCU USB PHY\n");
+ return -EINVAL;
+ }
+
+ priv->reg_bits = match->data;
+
+ priv->regmap = syscon_regmap_lookup_by_phandle(phynode,
+ "lantiq,rcu-syscon");
+ if (IS_ERR(priv->regmap)) {
+ dev_err(dev, "Failed to lookup RCU regmap\n");
+ return PTR_ERR(priv->regmap);
+ }
+
+ ret = ltq_rcu_usb2_get_vbus_gpios(dev, priv->gpiod_vbus);
+ if (ret) {
+ dev_err(dev, "failed to request shared USB VBUS GPIO\n");
+ return ret;
+ }
+
+ priv->ctrl_gate_clk = devm_clk_get(dev, "ctrl");
+ if (IS_ERR(priv->ctrl_gate_clk)) {
+ dev_err(dev, "Unable to get USB ctrl gate clk\n");
+ return PTR_ERR(priv->ctrl_gate_clk);
+ }
+
+ priv->phy_gate_clk = devm_clk_get(dev, "phy");
+ if (IS_ERR(priv->phy_gate_clk)) {
+ dev_err(dev, "Unable to get USB phy gate clk\n");
+ return PTR_ERR(priv->phy_gate_clk);
+ }
+
+ priv->ctrl_reset = devm_reset_control_get_shared(dev, "ctrl");
+ if (IS_ERR(priv->ctrl_reset)) {
+ dev_err(dev, "failed to get 'ctrl' reset\n");
+ return PTR_ERR(priv->ctrl_reset);
+ }
+
+ priv->phy_reset = devm_reset_control_get_optional(dev, "phy");
+ if (IS_ERR(priv->phy_reset)) {
+ if (PTR_ERR(priv->phy_reset) == -EPROBE_DEFER)
+ return PTR_ERR(priv->phy_reset);
+ priv->phy_reset = NULL;
+ }
+
+ ret = of_property_read_u32_index(phynode, "lantiq,rcu-syscon", 1,
+ &priv->phy_reg_offset);
+ if (ret) {
+ dev_err(dev, "Failed to get RCU PHY reg offset\n");
+ return ret;
+ }
+
+ if (priv->reg_bits->have_ana_cfg) {
+ ret = of_property_read_u32_index(phynode, "lantiq,rcu-syscon",
+ 2, &priv->ana_cfg1_reg_offset);
+ if (ret) {
+ dev_dbg(dev, "Failed to get RCU ANA CFG1 reg offset\n");
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static int ltq_rcu_usb2_phy_probe(struct platform_device *pdev)
+{
+ struct device_node *child, *np = pdev->dev.of_node;
+ struct ltq_rcu_usb2_priv *priv;
+ struct phy_provider *provider;
+ int ret;
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv),
+ GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->dev = &pdev->dev;
+ dev_set_drvdata(priv->dev, priv);
+
+ ret = ltq_rcu_usb2_of_probe(np, priv);
+ if (ret)
+ return ret;
+
+ priv->phy = devm_phy_create(&pdev->dev, child,
+ <q_rcu_usb2_phy_ops);
+ if (IS_ERR(priv->phy)) {
+ dev_err(&pdev->dev, "failed to create PHY\n");
+ return PTR_ERR(priv->phy);
+ }
+
+ phy_set_drvdata(priv->phy, priv);
+
+ ltq_rcu_usb2_start_cores(pdev);
+
+ provider = devm_of_phy_provider_register(&pdev->dev,
+ of_phy_simple_xlate);
+
+ return PTR_ERR_OR_ZERO(provider);
+}
+
+static struct platform_driver ltq_rcu_usb2_phy_driver = {
+ .probe = ltq_rcu_usb2_phy_probe,
+ .driver = {
+ .name = "lantiq-rcu-usb2-phy",
+ .of_match_table = ltq_rcu_usb2_phy_of_match,
+ }
+};
+module_platform_driver(ltq_rcu_usb2_phy_driver);
+
+MODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>");
+MODULE_DESCRIPTION("Lantiq XWAY USB2 PHY driver");
+MODULE_LICENSE("GPL v2");
--
2.11.0
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" 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
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