Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next v3 08/10] net: dsa: Add support for platform data
From: Florian Fainelli @ 2017-01-14 21:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170114214713.28109-1-f.fainelli@gmail.com>

Allow drivers to use the new DSA API with platform data. Most of the
code in net/dsa/dsa2.c does not rely so much on device_nodes and can get
the same information from platform_data instead.

We purposely do not support distributed configurations with platform
data, so drivers should be providing a pointer to a 'struct
dsa_chip_data' structure if they wish to communicate per-port layout.

Multiple CPUs port could potentially be supported and dsa_chip_data is
extended to receive up to one reference to an upstream network device
per port described by a dsa_chip_data structure.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 include/net/dsa.h |   6 ++++
 net/dsa/dsa2.c    | 101 ++++++++++++++++++++++++++++++++++++++++++++----------
 2 files changed, 89 insertions(+), 18 deletions(-)

diff --git a/include/net/dsa.h b/include/net/dsa.h
index 16a502a6c26a..491008792e4d 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -42,6 +42,11 @@ struct dsa_chip_data {
 	struct device	*host_dev;
 	int		sw_addr;
 
+	/*
+	 * Reference to network devices
+	 */
+	struct device	*netdev[DSA_MAX_PORTS];
+
 	/* set to size of eeprom if supported by the switch */
 	int		eeprom_len;
 
@@ -140,6 +145,7 @@ struct dsa_switch_tree {
 };
 
 struct dsa_port {
+	const char		*name;
 	struct net_device	*netdev;
 	struct device_node	*dn;
 	unsigned int		ageing_time;
diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c
index cd91070b5467..598229b02fd3 100644
--- a/net/dsa/dsa2.c
+++ b/net/dsa/dsa2.c
@@ -79,19 +79,28 @@ static void dsa_dst_del_ds(struct dsa_switch_tree *dst,
 	kref_put(&dst->refcount, dsa_free_dst);
 }
 
+/* For platform data configurations, we need to have a valid name argument to
+ * differentiate a disabled port from an enabled one
+ */
 static bool dsa_port_is_valid(struct dsa_port *port)
 {
-	return !!port->dn;
+	return !!(port->dn || port->name);
 }
 
 static bool dsa_port_is_dsa(struct dsa_port *port)
 {
-	return !!of_parse_phandle(port->dn, "link", 0);
+	if (port->name && !strcmp(port->name, "dsa"))
+		return true;
+	else
+		return !!of_parse_phandle(port->dn, "link", 0);
 }
 
 static bool dsa_port_is_cpu(struct dsa_port *port)
 {
-	return !!of_parse_phandle(port->dn, "ethernet", 0);
+	if (port->name && !strcmp(port->name, "cpu"))
+		return true;
+	else
+		return !!of_parse_phandle(port->dn, "ethernet", 0);
 }
 
 static bool dsa_ds_find_port_dn(struct dsa_switch *ds,
@@ -251,10 +260,11 @@ static void dsa_cpu_port_unapply(struct dsa_port *port, u32 index,
 static int dsa_user_port_apply(struct dsa_port *port, u32 index,
 			       struct dsa_switch *ds)
 {
-	const char *name;
+	const char *name = port->name;
 	int err;
 
-	name = of_get_property(port->dn, "label", NULL);
+	if (port->dn)
+		name = of_get_property(port->dn, "label", NULL);
 	if (!name)
 		name = "eth%d";
 
@@ -439,11 +449,15 @@ static int dsa_cpu_parse(struct dsa_port *port, u32 index,
 	struct net_device *ethernet_dev;
 	struct device_node *ethernet;
 
-	ethernet = of_parse_phandle(port->dn, "ethernet", 0);
-	if (!ethernet)
-		return -EINVAL;
+	if (port->dn) {
+		ethernet = of_parse_phandle(port->dn, "ethernet", 0);
+		if (!ethernet)
+			return -EINVAL;
+		ethernet_dev = of_find_net_device_by_node(ethernet);
+	} else {
+		ethernet_dev = dev_to_net_device(ds->cd->netdev[index]);
+	}
 
-	ethernet_dev = of_find_net_device_by_node(ethernet);
 	if (!ethernet_dev)
 		return -EPROBE_DEFER;
 
@@ -546,6 +560,33 @@ static int dsa_parse_ports_dn(struct device_node *ports, struct dsa_switch *ds)
 	return 0;
 }
 
+static int dsa_parse_ports(struct dsa_chip_data *cd, struct dsa_switch *ds)
+{
+	bool valid_name_found = false;
+	unsigned int i;
+
+	for (i = 0; i < DSA_MAX_PORTS; i++) {
+		if (!cd->port_names[i])
+			continue;
+
+		ds->ports[i].name = cd->port_names[i];
+
+		/* Initialize enabled_port_mask now for drv->setup()
+		 * to have access to a correct value, just like what
+		 * net/dsa/dsa.c::dsa_switch_setup_one does.
+		 */
+		if (!dsa_port_is_cpu(&ds->ports[i]))
+			ds->enabled_port_mask |= 1 << i;
+
+		valid_name_found = true;
+	}
+
+	if (!valid_name_found && i == DSA_MAX_PORTS)
+		return -EINVAL;
+
+	return 0;
+}
+
 static int dsa_parse_member_dn(struct device_node *np, u32 *tree, u32 *index)
 {
 	int err;
@@ -570,6 +611,18 @@ static int dsa_parse_member_dn(struct device_node *np, u32 *tree, u32 *index)
 	return 0;
 }
 
+static int dsa_parse_member(struct dsa_chip_data *pd, u32 *tree, u32 *index)
+{
+	if (!pd)
+		return -ENODEV;
+
+	/* We do not support complex trees with dsa_chip_data */
+	*tree = 0;
+	*index = 0;
+
+	return 0;
+}
+
 static struct device_node *dsa_get_ports(struct dsa_switch *ds,
 					 struct device_node *np)
 {
@@ -586,23 +639,34 @@ static struct device_node *dsa_get_ports(struct dsa_switch *ds,
 
 static int _dsa_register_switch(struct dsa_switch *ds, struct device *dev)
 {
+	struct dsa_chip_data *pdata = dev->platform_data;
 	struct device_node *np = dev->of_node;
 	struct dsa_switch_tree *dst;
 	struct device_node *ports;
 	u32 tree, index;
 	int i, err;
 
-	err = dsa_parse_member_dn(np, &tree, &index);
-	if (err)
-		return err;
+	if (np) {
+		err = dsa_parse_member_dn(np, &tree, &index);
+		if (err)
+			return err;
 
-	ports = dsa_get_ports(ds, np);
-	if (IS_ERR(ports))
-		return PTR_ERR(ports);
+		ports = dsa_get_ports(ds, np);
+		if (IS_ERR(ports))
+			return PTR_ERR(ports);
 
-	err = dsa_parse_ports_dn(ports, ds);
-	if (err)
-		return err;
+		err = dsa_parse_ports_dn(ports, ds);
+		if (err)
+			return err;
+	} else {
+		err = dsa_parse_member(pdata, &tree, &index);
+		if (err)
+			return err;
+
+		err = dsa_parse_ports(pdata, ds);
+		if (err)
+			return err;
+	}
 
 	dst = dsa_get_dst(tree);
 	if (!dst) {
@@ -618,6 +682,7 @@ static int _dsa_register_switch(struct dsa_switch *ds, struct device *dev)
 
 	ds->dst = dst;
 	ds->index = index;
+	ds->cd = pdata;
 
 	/* Initialize the routing table */
 	for (i = 0; i < DSA_MAX_SWITCHES; ++i)
-- 
2.9.3

^ permalink raw reply related

* [PATCH net-next v3 09/10] net: phy: Allow pre-declaration of MDIO devices
From: Florian Fainelli @ 2017-01-14 21:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170114214713.28109-1-f.fainelli@gmail.com>

Allow board support code to collect pre-declarations for MDIO devices by
registering them with mdiobus_register_board_info(). SPI and I2C buses
have a similar feature, we were missing this for MDIO devices, but this
is particularly useful for e.g: MDIO-connected switches which need to
provide their port layout (often board-specific) to a MDIO Ethernet
switch driver.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 drivers/net/phy/Makefile         |  3 +-
 drivers/net/phy/mdio-boardinfo.c | 86 ++++++++++++++++++++++++++++++++++++++++
 drivers/net/phy/mdio-boardinfo.h | 19 +++++++++
 drivers/net/phy/mdio_bus.c       |  4 ++
 drivers/net/phy/mdio_device.c    | 11 +++++
 include/linux/mdio.h             |  3 ++
 include/linux/mod_devicetable.h  |  1 +
 include/linux/phy.h              | 19 +++++++++
 8 files changed, 145 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/phy/mdio-boardinfo.c
 create mode 100644 drivers/net/phy/mdio-boardinfo.h

diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 356859ac7c18..407b0b601ea8 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -1,6 +1,7 @@
 # Makefile for Linux PHY drivers and MDIO bus drivers
 
-libphy-y			:= phy.o phy_device.o mdio_bus.o mdio_device.o
+libphy-y			:= phy.o phy_device.o mdio_bus.o mdio_device.o \
+				   mdio-boardinfo.o
 libphy-$(CONFIG_SWPHY)		+= swphy.o
 libphy-$(CONFIG_LED_TRIGGER_PHY)	+= phy_led_triggers.o
 
diff --git a/drivers/net/phy/mdio-boardinfo.c b/drivers/net/phy/mdio-boardinfo.c
new file mode 100644
index 000000000000..6b988f77da08
--- /dev/null
+++ b/drivers/net/phy/mdio-boardinfo.c
@@ -0,0 +1,86 @@
+/*
+ * mdio-boardinfo - Collect pre-declarations for MDIO devices
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/export.h>
+#include <linux/mutex.h>
+#include <linux/list.h>
+
+#include "mdio-boardinfo.h"
+
+static LIST_HEAD(mdio_board_list);
+static DEFINE_MUTEX(mdio_board_lock);
+
+/**
+ * mdiobus_setup_mdiodev_from_board_info - create and setup MDIO devices
+ * from pre-collected board specific MDIO information
+ * @mdiodev: MDIO device pointer
+ * Context: can sleep
+ */
+void mdiobus_setup_mdiodev_from_board_info(struct mii_bus *bus)
+{
+	struct mdio_board_entry *be;
+	struct mdio_device *mdiodev;
+	struct mdio_board_info *bi;
+	int ret;
+
+	mutex_lock(&mdio_board_lock);
+	list_for_each_entry(be, &mdio_board_list, list) {
+		bi = &be->board_info;
+
+		if (strcmp(bus->id, bi->bus_id))
+			continue;
+
+		mdiodev = mdio_device_create(bus, bi->mdio_addr);
+		if (IS_ERR(mdiodev))
+			continue;
+
+		strncpy(mdiodev->modalias, bi->modalias,
+			sizeof(mdiodev->modalias));
+		mdiodev->bus_match = mdio_device_bus_match;
+		mdiodev->dev.platform_data = (void *)bi->platform_data;
+
+		ret = mdio_device_register(mdiodev);
+		if (ret) {
+			mdio_device_free(mdiodev);
+			continue;
+		}
+	}
+	mutex_unlock(&mdio_board_lock);
+}
+
+/**
+ * mdio_register_board_info - register MDIO devices for a given board
+ * @info: array of devices descriptors
+ * @n: number of descriptors provided
+ * Context: can sleep
+ *
+ * The board info passed can be marked with __initdata but be pointers
+ * such as platform_data etc. are copied as-is
+ */
+int mdiobus_register_board_info(const struct mdio_board_info *info,
+				unsigned int n)
+{
+	struct mdio_board_entry *be;
+	unsigned int i;
+
+	be = kcalloc(n, sizeof(*be), GFP_KERNEL);
+	if (!be)
+		return -ENOMEM;
+
+	for (i = 0; i < n; i++, be++, info++) {
+		memcpy(&be->board_info, info, sizeof(*info));
+		mutex_lock(&mdio_board_lock);
+		list_add_tail(&be->list, &mdio_board_list);
+		mutex_unlock(&mdio_board_lock);
+	}
+
+	return 0;
+}
diff --git a/drivers/net/phy/mdio-boardinfo.h b/drivers/net/phy/mdio-boardinfo.h
new file mode 100644
index 000000000000..00f98163e90e
--- /dev/null
+++ b/drivers/net/phy/mdio-boardinfo.h
@@ -0,0 +1,19 @@
+/*
+ * mdio-boardinfo.h - board info interface internal to the mdio_bus
+ * component
+ */
+
+#ifndef __MDIO_BOARD_INFO_H
+#define __MDIO_BOARD_INFO_H
+
+#include <linux/phy.h>
+#include <linux/mutex.h>
+
+struct mdio_board_entry {
+	struct list_head	list;
+	struct mdio_board_info	board_info;
+};
+
+void mdiobus_setup_mdiodev_from_board_info(struct mii_bus *bus);
+
+#endif /* __MDIO_BOARD_INFO_H */
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 653d076eafe5..fa7d51f14869 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -41,6 +41,8 @@
 #define CREATE_TRACE_POINTS
 #include <trace/events/mdio.h>
 
+#include "mdio-boardinfo.h"
+
 int mdiobus_register_device(struct mdio_device *mdiodev)
 {
 	if (mdiodev->bus->mdio_map[mdiodev->addr])
@@ -343,6 +345,8 @@ int __mdiobus_register(struct mii_bus *bus, struct module *owner)
 		}
 	}
 
+	mdiobus_setup_mdiodev_from_board_info(bus);
+
 	bus->state = MDIOBUS_REGISTERED;
 	pr_info("%s: probed\n", bus->name);
 	return 0;
diff --git a/drivers/net/phy/mdio_device.c b/drivers/net/phy/mdio_device.c
index fc3aaaa36b1d..e24f28924af8 100644
--- a/drivers/net/phy/mdio_device.c
+++ b/drivers/net/phy/mdio_device.c
@@ -34,6 +34,17 @@ static void mdio_device_release(struct device *dev)
 	kfree(to_mdio_device(dev));
 }
 
+int mdio_device_bus_match(struct device *dev, struct device_driver *drv)
+{
+	struct mdio_device *mdiodev = to_mdio_device(dev);
+	struct mdio_driver *mdiodrv = to_mdio_driver(drv);
+
+	if (mdiodrv->mdiodrv.flags & MDIO_DEVICE_IS_PHY)
+		return 0;
+
+	return strcmp(mdiodev->modalias, drv->name) == 0;
+}
+
 struct mdio_device *mdio_device_create(struct mii_bus *bus, int addr)
 {
 	struct mdio_device *mdiodev;
diff --git a/include/linux/mdio.h b/include/linux/mdio.h
index b6587a4b32e7..00a7f43c1482 100644
--- a/include/linux/mdio.h
+++ b/include/linux/mdio.h
@@ -10,6 +10,7 @@
 #define __LINUX_MDIO_H__
 
 #include <uapi/linux/mdio.h>
+#include <linux/mod_devicetable.h>
 
 struct mii_bus;
 
@@ -29,6 +30,7 @@ struct mdio_device {
 
 	const struct dev_pm_ops *pm_ops;
 	struct mii_bus *bus;
+	char modalias[MDIO_NAME_SIZE];
 
 	int (*bus_match)(struct device *dev, struct device_driver *drv);
 	void (*device_free)(struct mdio_device *mdiodev);
@@ -71,6 +73,7 @@ int mdio_device_register(struct mdio_device *mdiodev);
 void mdio_device_remove(struct mdio_device *mdiodev);
 int mdio_driver_register(struct mdio_driver *drv);
 void mdio_driver_unregister(struct mdio_driver *drv);
+int mdio_device_bus_match(struct device *dev, struct device_driver *drv);
 
 static inline bool mdio_phy_id_is_c45(int phy_id)
 {
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 8a57f0b1242d..8850fcaf50db 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -501,6 +501,7 @@ struct platform_device_id {
 	kernel_ulong_t driver_data;
 };
 
+#define MDIO_NAME_SIZE		32
 #define MDIO_MODULE_PREFIX	"mdio:"
 
 #define MDIO_ID_FMT "%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d"
diff --git a/include/linux/phy.h b/include/linux/phy.h
index f7d95f644eed..7745f7391d3e 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -882,6 +882,25 @@ void mdio_bus_exit(void);
 
 extern struct bus_type mdio_bus_type;
 
+struct mdio_board_info {
+	const char	*bus_id;
+	char		modalias[MDIO_NAME_SIZE];
+	int		mdio_addr;
+	const void	*platform_data;
+};
+
+#if IS_ENABLED(CONFIG_PHYLIB)
+int mdiobus_register_board_info(const struct mdio_board_info *info,
+				unsigned int n);
+#else
+static inline int mdiobus_register_board_info(const struct mdio_board_info *i,
+					      unsigned int n)
+{
+	return 0;
+}
+#endif
+
+
 /**
  * module_phy_driver() - Helper macro for registering PHY drivers
  * @__phy_drivers: array of PHY drivers to register
-- 
2.9.3

^ permalink raw reply related

* [PATCH net-next v3 10/10] ARM: orion: Register DSA switch as a MDIO device
From: Florian Fainelli @ 2017-01-14 21:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170114214713.28109-1-f.fainelli@gmail.com>

Utilize the ability to pass board specific MDIO bus information towards a
particular MDIO device thus allowing us to provide the per-port switch layout
to the Marvell 88E6XXX switch driver.

Since we would end-up with conflicting registration paths, do not register the
"dsa" platform device anymore.

Note that the MDIO devices registered by code in net/dsa/dsa2.c does not
parse a dsa_platform_data, but directly take a dsa_chip_data (specific
to a single switch chip), so we update the different call sites to pass
this structure down to orion_ge00_switch_init().

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 arch/arm/mach-orion5x/common.c               |  2 +-
 arch/arm/mach-orion5x/common.h               |  4 ++--
 arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c |  7 +------
 arch/arm/mach-orion5x/rd88f5181l-ge-setup.c  |  7 +------
 arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c |  7 +------
 arch/arm/mach-orion5x/wnr854t-setup.c        |  2 +-
 arch/arm/mach-orion5x/wrt350n-v2-setup.c     |  7 +------
 arch/arm/plat-orion/common.c                 | 25 +++++++++++++++++++------
 arch/arm/plat-orion/include/plat/common.h    |  4 ++--
 9 files changed, 29 insertions(+), 36 deletions(-)

diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c
index 04910764c385..83a7ec4c16d0 100644
--- a/arch/arm/mach-orion5x/common.c
+++ b/arch/arm/mach-orion5x/common.c
@@ -105,7 +105,7 @@ void __init orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data)
 /*****************************************************************************
  * Ethernet switch
  ****************************************************************************/
-void __init orion5x_eth_switch_init(struct dsa_platform_data *d)
+void __init orion5x_eth_switch_init(struct dsa_chip_data *d)
 {
 	orion_ge00_switch_init(d);
 }
diff --git a/arch/arm/mach-orion5x/common.h b/arch/arm/mach-orion5x/common.h
index 8a4115bd441d..efeffc6b4ebb 100644
--- a/arch/arm/mach-orion5x/common.h
+++ b/arch/arm/mach-orion5x/common.h
@@ -3,7 +3,7 @@
 
 #include <linux/reboot.h>
 
-struct dsa_platform_data;
+struct dsa_chip_data;
 struct mv643xx_eth_platform_data;
 struct mv_sata_platform_data;
 
@@ -41,7 +41,7 @@ void orion5x_setup_wins(void);
 void orion5x_ehci0_init(void);
 void orion5x_ehci1_init(void);
 void orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data);
-void orion5x_eth_switch_init(struct dsa_platform_data *d);
+void orion5x_eth_switch_init(struct dsa_chip_data *d);
 void orion5x_i2c_init(void);
 void orion5x_sata_init(struct mv_sata_platform_data *sata_data);
 void orion5x_spi_init(void);
diff --git a/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c b/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c
index dccadf68ea2b..a3c1336d30c9 100644
--- a/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c
+++ b/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c
@@ -101,11 +101,6 @@ static struct dsa_chip_data rd88f5181l_fxo_switch_chip_data = {
 	.port_names[7]	= "lan3",
 };
 
-static struct dsa_platform_data __initdata rd88f5181l_fxo_switch_plat_data = {
-	.nr_chips	= 1,
-	.chip		= &rd88f5181l_fxo_switch_chip_data,
-};
-
 static void __init rd88f5181l_fxo_init(void)
 {
 	/*
@@ -120,7 +115,7 @@ static void __init rd88f5181l_fxo_init(void)
 	 */
 	orion5x_ehci0_init();
 	orion5x_eth_init(&rd88f5181l_fxo_eth_data);
-	orion5x_eth_switch_init(&rd88f5181l_fxo_switch_plat_data);
+	orion5x_eth_switch_init(&rd88f5181l_fxo_switch_chip_data);
 	orion5x_uart0_init();
 
 	mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET,
diff --git a/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c b/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c
index affe5ec825de..252efe29bd1a 100644
--- a/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c
+++ b/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c
@@ -102,11 +102,6 @@ static struct dsa_chip_data rd88f5181l_ge_switch_chip_data = {
 	.port_names[7]	= "lan3",
 };
 
-static struct dsa_platform_data __initdata rd88f5181l_ge_switch_plat_data = {
-	.nr_chips	= 1,
-	.chip		= &rd88f5181l_ge_switch_chip_data,
-};
-
 static struct i2c_board_info __initdata rd88f5181l_ge_i2c_rtc = {
 	I2C_BOARD_INFO("ds1338", 0x68),
 };
@@ -125,7 +120,7 @@ static void __init rd88f5181l_ge_init(void)
 	 */
 	orion5x_ehci0_init();
 	orion5x_eth_init(&rd88f5181l_ge_eth_data);
-	orion5x_eth_switch_init(&rd88f5181l_ge_switch_plat_data);
+	orion5x_eth_switch_init(&rd88f5181l_ge_switch_chip_data);
 	orion5x_i2c_init();
 	orion5x_uart0_init();
 
diff --git a/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c b/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c
index 67ee8571b03c..f4f1dbe1d91d 100644
--- a/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c
+++ b/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c
@@ -40,11 +40,6 @@ static struct dsa_chip_data rd88f6183ap_ge_switch_chip_data = {
 	.port_names[5]	= "cpu",
 };
 
-static struct dsa_platform_data __initdata rd88f6183ap_ge_switch_plat_data = {
-	.nr_chips	= 1,
-	.chip		= &rd88f6183ap_ge_switch_chip_data,
-};
-
 static struct mtd_partition rd88f6183ap_ge_partitions[] = {
 	{
 		.name	= "kernel",
@@ -89,7 +84,7 @@ static void __init rd88f6183ap_ge_init(void)
 	 */
 	orion5x_ehci0_init();
 	orion5x_eth_init(&rd88f6183ap_ge_eth_data);
-	orion5x_eth_switch_init(&rd88f6183ap_ge_switch_plat_data);
+	orion5x_eth_switch_init(&rd88f6183ap_ge_switch_chip_data);
 	spi_register_board_info(rd88f6183ap_ge_spi_slave_info,
 				ARRAY_SIZE(rd88f6183ap_ge_spi_slave_info));
 	orion5x_spi_init();
diff --git a/arch/arm/mach-orion5x/wnr854t-setup.c b/arch/arm/mach-orion5x/wnr854t-setup.c
index 4dbcdbe1de7c..ac3376fc269f 100644
--- a/arch/arm/mach-orion5x/wnr854t-setup.c
+++ b/arch/arm/mach-orion5x/wnr854t-setup.c
@@ -124,7 +124,7 @@ static void __init wnr854t_init(void)
 	 * Configure peripherals.
 	 */
 	orion5x_eth_init(&wnr854t_eth_data);
-	orion5x_eth_switch_init(&wnr854t_switch_plat_data);
+	orion5x_eth_switch_init(&wnr854t_switch_chip_data);
 	orion5x_uart0_init();
 
 	mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET,
diff --git a/arch/arm/mach-orion5x/wrt350n-v2-setup.c b/arch/arm/mach-orion5x/wrt350n-v2-setup.c
index a6a8c4648d74..9250bb2e429c 100644
--- a/arch/arm/mach-orion5x/wrt350n-v2-setup.c
+++ b/arch/arm/mach-orion5x/wrt350n-v2-setup.c
@@ -191,11 +191,6 @@ static struct dsa_chip_data wrt350n_v2_switch_chip_data = {
 	.port_names[7]	= "lan4",
 };
 
-static struct dsa_platform_data __initdata wrt350n_v2_switch_plat_data = {
-	.nr_chips	= 1,
-	.chip		= &wrt350n_v2_switch_chip_data,
-};
-
 static void __init wrt350n_v2_init(void)
 {
 	/*
@@ -210,7 +205,7 @@ static void __init wrt350n_v2_init(void)
 	 */
 	orion5x_ehci0_init();
 	orion5x_eth_init(&wrt350n_v2_eth_data);
-	orion5x_eth_switch_init(&wrt350n_v2_switch_plat_data);
+	orion5x_eth_switch_init(&wrt350n_v2_switch_chip_data);
 	orion5x_uart0_init();
 
 	mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET,
diff --git a/arch/arm/plat-orion/common.c b/arch/arm/plat-orion/common.c
index 272f49b2c68f..9255b6d67ba5 100644
--- a/arch/arm/plat-orion/common.c
+++ b/arch/arm/plat-orion/common.c
@@ -22,6 +22,7 @@
 #include <linux/platform_data/dma-mv_xor.h>
 #include <linux/platform_data/usb-ehci-orion.h>
 #include <plat/common.h>
+#include <linux/phy.h>
 
 /* Create a clkdev entry for a given device/clk */
 void __init orion_clkdev_add(const char *con_id, const char *dev_id,
@@ -470,15 +471,27 @@ void __init orion_ge11_init(struct mv643xx_eth_platform_data *eth_data,
 /*****************************************************************************
  * Ethernet switch
  ****************************************************************************/
-void __init orion_ge00_switch_init(struct dsa_platform_data *d)
+static __initconst const char *orion_ge00_mvmdio_bus_name = "orion-mii";
+static __initdata struct mdio_board_info
+		  orion_ge00_switch_board_info;
+
+void __init orion_ge00_switch_init(struct dsa_chip_data *d)
 {
-	int i;
+	struct mdio_board_info *bd;
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(d->port_names); i++)
+		if (!strcmp(d->port_names[i], "cpu"))
+			break;
 
-	d->netdev = &orion_ge00.dev;
-	for (i = 0; i < d->nr_chips; i++)
-		d->chip[i].host_dev = &orion_ge_mvmdio.dev;
+	bd = &orion_ge00_switch_board_info;
+	bd->bus_id = orion_ge00_mvmdio_bus_name;
+	bd->mdio_addr = d->sw_addr;
+	d->netdev[i] = &orion_ge00.dev;
+	strcpy(bd->modalias, "mv88e6085");
+	bd->platform_data = d;
 
-	platform_device_register_data(NULL, "dsa", 0, d, sizeof(d));
+	mdiobus_register_board_info(&orion_ge00_switch_board_info, 1);
 }
 
 /*****************************************************************************
diff --git a/arch/arm/plat-orion/include/plat/common.h b/arch/arm/plat-orion/include/plat/common.h
index 9347f3c58a6d..3647d3b33c20 100644
--- a/arch/arm/plat-orion/include/plat/common.h
+++ b/arch/arm/plat-orion/include/plat/common.h
@@ -12,7 +12,7 @@
 #include <linux/mv643xx_eth.h>
 #include <linux/platform_data/usb-ehci-orion.h>
 
-struct dsa_platform_data;
+struct dsa_chip_data;
 struct mv_sata_platform_data;
 
 void __init orion_uart0_init(void __iomem *membase,
@@ -57,7 +57,7 @@ void __init orion_ge11_init(struct mv643xx_eth_platform_data *eth_data,
 			    unsigned long mapbase,
 			    unsigned long irq);
 
-void __init orion_ge00_switch_init(struct dsa_platform_data *d);
+void __init orion_ge00_switch_init(struct dsa_chip_data *d);
 
 void __init orion_i2c_init(unsigned long mapbase,
 			   unsigned long irq,
-- 
2.9.3

^ permalink raw reply related

* [PATCH v3 16/24] media: Add i.MX media core driver
From: Steve Longerbeam @ 2017-01-14 22:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484320822.31475.96.camel@pengutronix.de>

(sorry sending again w/o html)


On 01/13/2017 07:20 AM, Philipp Zabel wrote:
> Am Freitag, den 06.01.2017, 18:11 -0800 schrieb Steve Longerbeam:
>> +For image capture, the IPU contains the following internal subunits:
>> +
>> +- Image DMA Controller (IDMAC)
>> +- Camera Serial Interface (CSI)
>> +- Image Converter (IC)
>> +- Sensor Multi-FIFO Controller (SMFC)
>> +- Image Rotator (IRT)
>> +- Video De-Interlace Controller (VDIC)
> Nitpick: Video De-Interlacing or Combining Block (VDIC)

done.

>> +
>> +The IDMAC is the DMA controller for transfer of image frames to and from
>> +memory. Various dedicated DMA channels exist for both video capture and
>> +display paths.
>> +
>> +The CSI is the frontend capture unit that interfaces directly with
>> +capture sensors over Parallel, BT.656/1120, and MIPI CSI-2 busses.
>> +
>> +The IC handles color-space conversion, resizing, and rotation
>> +operations.
> And horizontal flipping.

done.


>> There are three independent "tasks" within the IC that can
>> +carry out conversions concurrently: pre-processing encoding,
>> +pre-processing preview, and post-processing.
> s/preview/viewfinder/ seems to be the commonly used name.

replaced everywhere in the doc.

> This paragraph could mention that a single hardware unit is used
> transparently time multiplexed by the three tasks at different
> granularity for the downsizing, main processing, and rotation sections.
> The downscale unit switches between tasks at 8-pixel burst granularity,
> the main processing unit at line granularity. The rotation units switch
> only at frame granularity.

I've added that info.

>> +The SMFC is composed of four independent channels that each can transfer
>> +captured frames from sensors directly to memory concurrently.
>> +
>> +The IRT carries out 90 and 270 degree image rotation operations.
> ... on 8x8 pixel blocks, supported by the IDMAC which handles block
> transfers, block reordering, and vertical flipping.

done.

>> +The VDIC handles the conversion of interlaced video to progressive, with
>> +support for different motion compensation modes (low, medium, and high
>> +motion). The deinterlaced output frames from the VDIC can be sent to the
>> +IC pre-process preview task for further conversions.
>> +
>> +In addition to the IPU internal subunits, there are also two units
>> +outside the IPU that are also involved in video capture on i.MX:
>> +
>> +- MIPI CSI-2 Receiver for camera sensors with the MIPI CSI-2 bus
>> +  interface. This is a Synopsys DesignWare core.
>> +- A video multiplexer for selecting among multiple sensor inputs to
>> +  send to a CSI.
> Two of them, actually.

done.

>> +
>> +- Includes a Frame Interval Monitor (FIM) that can correct vertical sync
>> +  problems with the ADV718x video decoders. See below for a description
>> +  of the FIM.
> Could this also be used to calculate more precise capture timestamps?

An input capture function could do that, triggered off a VSYNC or FIELD
signal such as on the ADV718x. The FIM is only used to calculate
frame intervals at this point, but its input capture method could be
used to also record more accurate timestamps.


>> +Capture Pipelines
>> +-----------------
>> +
>> +The following describe the various use-cases supported by the pipelines.
>> +
>> +The links shown do not include the frontend sensor, video mux, or mipi
>> +csi-2 receiver links. This depends on the type of sensor interface
>> +(parallel or mipi csi-2). So in all cases, these pipelines begin with:
>> +
>> +sensor -> ipu_csi_mux -> ipu_csi -> ...
>> +
>> +for parallel sensors, or:
>> +
>> +sensor -> imx-mipi-csi2 -> (ipu_csi_mux) -> ipu_csi -> ...
>> +
>> +for mipi csi-2 sensors. The imx-mipi-csi2 receiver may need to route
>> +to the video mux (ipu_csi_mux) before sending to the CSI, depending
>> +on the mipi csi-2 virtual channel, hence ipu_csi_mux is shown in
>> +parenthesis.
>> +
>> +Unprocessed Video Capture:
>> +--------------------------
>> +
>> +Send frames directly from sensor to camera interface, with no
>> +conversions:
>> +
>> +-> ipu_smfc -> camif
> I'd call this capture interface, this is not just for cameras. Or maybe
> idmac if you want to mirror hardware names?

Camif is so named because it is the V4L2 user interface for video
capture. I suppose it could be named "capif", but that doesn't role
off the tongue quite as well.

>> +Note the ipu_smfc can do pixel reordering within the same colorspace.
> That isn't a feature of the SMFC, but of the IDMAC (FCW & FCR).

yes, the doc is re-worded to make that more clear.

>> +For example, its sink pad can take UYVY2X8, but its source pad can
>> +output YUYV2X8.
> I don't think this is correct. Re-reading "37.4.3.7 Packing to memory"
> in the CSI chapter, for 8-bit per component data, the internal format
> between CSI, SMFC, and IDMAC is always some 32-bit RGBx/YUVx variant
> (or "bayer/generic data"). In either case, the internal format does not
> change along the way.

these are pixels in memory buffers, not the IPU internal formats.


>> +IC Direct Conversions:
>> +----------------------
>> +
>> +This pipeline uses the preprocess encode entity to route frames directly
>> +from the CSI to the IC (bypassing the SMFC), to carry out scaling up to
>> +1024x1024 resolution, CSC, and image rotation:
>> +
>> +-> ipu_ic_prpenc -> camif
>> +
>> +This can be a useful capture pipeline for heavily loaded memory bus
>> +traffic environments, since it has minimal IDMAC channel usage.
> Note that if rotation is enabled, transfers between IC processing and
> rotation still have to go through memory once.

yep.

>> +Post-Processing Conversions:
>> +----------------------------
>> +
>> +This pipeline routes frames from the SMFC to the post-processing
>> +entity.
> No, frames written by the CSI -> SMFC -> IDMAC path are read back into
> the post-processing entity.

that's true. The post-processing entity kicks off its read channels
to transfer those frames into the post-processor. Anyway this wording
will change after doing away with the SMFC entity.


>> +   media-ctl -V "\"ipu1_csi0\":1 [fmt:YUYV2X8/640x480]"
>> +   media-ctl -V "\"ipu1_smfc0\":0 [fmt:YUYV2X8/640x480]"
>> +   media-ctl -V "\"ipu1_smfc0\":1 [fmt:UYVY2X8/640x480]"
> I think the smfc entities should be dropped.

yes working on that.

>> +   media-ctl -V "\"camif0\":0 [fmt:UYVY2X8/640x480]"
>> +   media-ctl -V "\"camif0\":1 [fmt:UYVY2X8/640x480]"
>> +   # Configure pads for OV5640 pipeline
>> +   media-ctl -V "\"ov5640_mipi 1-0040\":0 [fmt:UYVY2X8/640x480]"
>> +   media-ctl -V "\"imx-mipi-csi2\":0 [fmt:UYVY2X8/640x480]"
>> +   media-ctl -V "\"imx-mipi-csi2\":2 [fmt:UYVY2X8/640x480]"
>> +   media-ctl -V "\"ipu1_csi1\":0 [fmt:UYVY2X8/640x480]"
>> +   media-ctl -V "\"ipu1_csi1\":1 [fmt:UYVY2X8/640x480]"
> [...]
>> +   media-ctl -V "\"camif1\":0 [fmt:UYVY2X8/640x480]"
> I agree this looks very intuitive, but technically correct for the
> csi1:1 and camif1:0 pads would be a 32-bit YUV format.
> (MEDIA_BUS_FMT_YUV8_1X32_PADLO doesn't exist yet).
>
> I think it would be better to use the correct format

I'm not sure I follow you here.

>   as that will allow
> to chose the regular vs. companded packings in the future for formats
> with more than 8 bits per component.
>
>> +   media-ctl -V "\"camif1\":1 [fmt:UYVY2X8/640x480]"
>> +
>> +Streaming can then begin independently on device nodes /dev/video0
>> +and /dev/video1.
>> +
>> +SabreAuto with ADV7180 decoder
>> +------------------------------
>> +
>> +On the SabreAuto, an on-board ADV7180 SD decoder is connected to the
>> +parallel bus input on the internal video mux to IPU1 CSI0.
>> +
>> +The following example configures a pipeline to capture from the ADV7180
>> +video decoder, assuming NTSC 720x480 input signals, with Motion
>> +Compensated de-interlacing (not shown: all pad field types should be set
>> +as indicated). $outputfmt can be any format supported by the
>> +ipu1_ic_prpvf entity at its output pad:
>> +
>> +.. code-block:: none
>> +
>> +   # Setup links
>> +   media-ctl -l '"adv7180 3-0021":0 -> "ipu1_csi0_mux":1[1]'
>> +   media-ctl -l '"ipu1_csi0_mux":2 -> "ipu1_csi0":0[1]'
>> +   media-ctl -l '"ipu1_csi0":1 -> "ipu1_smfc0":0[1]'
>> +   media-ctl -l '"ipu1_smfc0":1 -> "ipu1_ic_prpvf":0[1]'
>> +   media-ctl -l '"ipu1_ic_prpvf":1 -> "camif0":0[1]'
>> +   media-ctl -l '"camif0":1 -> "camif0 devnode":0[1]'
>> +   # Configure pads
>> +   # pad field types for below pads must be an interlaced type
>> +   # such as "ALTERNATE"
> I think alternate should only extend as far as the CSI, since the CSI
> can only capture NTSC/PAL fields in a fixed order.

Agreed, I'm doing the translation from alternate to seq_bt/seq_tb depending
on sensor std in imx-vdic.c, but it should move upstream. Will fix.

>> +   media-ctl -V "\"adv7180 3-0021\":0 [fmt:UYVY2X8/720x480]"
>> +   media-ctl -V "\"ipu1_csi0_mux\":1 [fmt:UYVY2X8/720x480]"
>  From here the interlaced field type should be sequential in the correct
> order depending on NTSC/PAL.

right.

>> +
>> +Frame Interval Monitor
>> +----------------------
>> +
>> +The adv718x decoders can occasionally send corrupt fields during
>> +NTSC/PAL signal re-sync (too little or too many video lines). When
>> +this happens, the IPU triggers a mechanism to re-establish vertical
>> +sync by adding 1 dummy line every frame, which causes a rolling effect
>> +from image to image, and can last a long time before a stable image is
>> +recovered. Or sometimes the mechanism doesn't work at all, causing a
>> +permanent split image (one frame contains lines from two consecutive
>> +captured images).
> Is it only SabreAuto on which the FIM mechanism can be used due to the
> pad routing?

No, FIM can be used on any target, the fim child node of ipu_csi just
needs to be enabled via status property.

> [...]
>> +/*
>> + * DMA buffer ring handling
>> + */
>> +struct imx_media_dma_buf_ring {
>> +	struct imx_media_dev *imxmd;
>> +
>> +	/* the ring */
>> +	struct imx_media_dma_buf buf[IMX_MEDIA_MAX_RING_BUFS];
>> +	/* the scratch buffer for underruns */
>> +	struct imx_media_dma_buf scratch;
>> +
>> +	/* buffer generator */
>> +	struct media_entity *src;
>> +	/* buffer receiver */
>> +	struct media_entity *sink;
>> +
>> +	spinlock_t lock;
>> +
>> +	int num_bufs;
>> +	unsigned long last_seq;
>> +};
> I don't think this belongs in the capture driver at all.
> Memory-to-memory transfers should be handled at the videobuf2 level.

see below.

> [...]
>> +static struct imx_media_dma_buf *
>> +__dma_buf_queue(struct imx_media_dma_buf_ring *ring, int index)
>> +{
>> +	struct imx_media_dma_buf *buf;
>> +
>> +	if (index >= ring->num_bufs)
>> +		return ERR_PTR(-EINVAL);
>> +
>> +	buf = &ring->buf[index];
>> +	if (WARN_ON(buf->state != IMX_MEDIA_BUF_STATUS_PREPARED))
>> +		return ERR_PTR(-EINVAL);
>> +
>> +	buf->state = IMX_MEDIA_BUF_STATUS_QUEUED;
>> +	buf->seq = ring->last_seq++;
>> +
>> +	return buf;
>> +}
> Is this a whole software buffer queue implementation? I thought the
> whole point of putting the custom mem2mem framework into the capture
> driver was to use the hardware FSU channel linking?

  see below.

> What is the purpose of this if the sink should be triggered by the FSU?

Ok, here is where I need to make an admission.

The only FSU links I have attempted (and which currently have entries
in the fsu_link_info[] table), are the enc/vf/pp --> IRT links for rotation.

There does not appear to be support in the FSU for linking a write channel
to the VDIC read channels (8, 9, 10) according to VDI_SRC_SEL field. There
is support for the direct link from CSI (which I am using), but that's 
not an
IDMAC channel link.

There is a PRP_SRC_SEL field, with linking from IDMAC (SMFC) channels
0..2 (and 3? it's not clear, and not clear whether this includes channel 1).
But I think this links to channel 12, and not to channels 8,9,10 to the 
VDIC.
Or will it? It's worth experimenting. It would have helped if FSL listed 
which
IDMAC channels these FSU links correspond to, instead of making us guess
at it.

In any event, the docs are not clear enough to implement a real FSU
link to the VDIC read channels, if it's even possible. And trying to get
programming help from FSL can be difficult, and no coding examples
for this link AFAIK.

So I ended resorted to linking to VDIC channels 8,9,10 with a software
approach, instead of attempting a hardware FSU link.

The EOF interrupt handler for the SMFC channels informs the VDIC
entity via a v4l2_subdev_ioctl() call that a buffer is available. The
VDIC then manually kicks off its read channels to bring that buffer
(and a previous buffer for F(n-1) field) into the VDIC.

There is a small amount of extra overhead going this route compared
to a FSU hardware link: there is the EOF irq latency (a few usec), and
the CPU overhead for the VDIC to manually start the read channels,
which is also a few usec at most (see prepare_vdi_in_buffers() in
imx-vdic.c). So in total at most ~10 usec of extra overhead (CPU
use plus irq latency) under normal system load.

Of course, in order to implement this software link, I had to implement
a straightforward FIFO dma buffer ring. The sink (VDIC) allocates the ring
at stream on, and the source requests a pointer to this ring in its own
stream on. Passing buffers from source to sink then follows a 
straightforward
FIFO queue/done/dequeue/queue model: sink queues buffers to src, src
grabs queued buffers and makes them active, src signals completed
buffers to sink, sink dequeues buffers in response, and sink queues
buffers back when it is finished with them.


> [...]
>> +/*
>> + * The subdevs have to be powered on/off, and streaming
>> + * enabled/disabled, in a specific sequence.
>> + */
>> +static const u32 stream_on_seq[] = {
>> +	IMX_MEDIA_GRP_ID_IC_PP,
>> +	IMX_MEDIA_GRP_ID_IC_PRPVF,
>> +	IMX_MEDIA_GRP_ID_IC_PRPENC,
>> +	IMX_MEDIA_GRP_ID_SMFC,
>> +	IMX_MEDIA_GRP_ID_SENSOR,
>> +	IMX_MEDIA_GRP_ID_CSI2,
>> +	IMX_MEDIA_GRP_ID_VIDMUX,
>> +	IMX_MEDIA_GRP_ID_CSI,
>> +};
>> +
>> +static const u32 stream_off_seq[] = {
>> +	IMX_MEDIA_GRP_ID_IC_PP,
>> +	IMX_MEDIA_GRP_ID_IC_PRPVF,
>> +	IMX_MEDIA_GRP_ID_IC_PRPENC,
>> +	IMX_MEDIA_GRP_ID_SMFC,
>> +	IMX_MEDIA_GRP_ID_CSI,
>> +	IMX_MEDIA_GRP_ID_VIDMUX,
>> +	IMX_MEDIA_GRP_ID_CSI2,
>> +	IMX_MEDIA_GRP_ID_SENSOR,
>> +};
>> +
>> +#define NUM_STREAM_ENTITIES ARRAY_SIZE(stream_on_seq)
>> +
>> +static const u32 power_on_seq[] = {
>> +	IMX_MEDIA_GRP_ID_CSI2,
>> +	IMX_MEDIA_GRP_ID_SENSOR,
>> +	IMX_MEDIA_GRP_ID_VIDMUX,
>> +	IMX_MEDIA_GRP_ID_CSI,
>> +	IMX_MEDIA_GRP_ID_SMFC,
>> +	IMX_MEDIA_GRP_ID_IC_PRPENC,
>> +	IMX_MEDIA_GRP_ID_IC_PRPVF,
>> +	IMX_MEDIA_GRP_ID_IC_PP,
>> +};
>> +
>> +static const u32 power_off_seq[] = {
>> +	IMX_MEDIA_GRP_ID_IC_PP,
>> +	IMX_MEDIA_GRP_ID_IC_PRPVF,
>> +	IMX_MEDIA_GRP_ID_IC_PRPENC,
>> +	IMX_MEDIA_GRP_ID_SMFC,
>> +	IMX_MEDIA_GRP_ID_CSI,
>> +	IMX_MEDIA_GRP_ID_VIDMUX,
>> +	IMX_MEDIA_GRP_ID_SENSOR,
>> +	IMX_MEDIA_GRP_ID_CSI2,
>> +};
> This seems somewhat arbitrary. Why is a power sequence needed?

The CSI-2 receiver must be powered up before the sensor, that's the
only requirement IIRC. The others have no s_power requirement. So I
can probably change this to power up in the frontend -> backend order
(IC_PP to sensor). And vice-versa for power off.


> [...]
>> +/*
>> + * Turn current pipeline power on/off starting from start_entity.
>> + * Must be called with mdev->graph_mutex held.
>> + */
>> +int imx_media_pipeline_set_power(struct imx_media_dev *imxmd,
>> +				 struct media_entity_graph *graph,
>> +				 struct media_entity *start_entity, bool on)
>> +{
>> +	struct media_entity *entity;
>> +	struct v4l2_subdev *sd;
>> +	int i, ret = 0;
>> +	u32 id;
>> +
>> +	for (i = 0; i < NUM_POWER_ENTITIES; i++) {
>> +		id = on ? power_on_seq[i] : power_off_seq[i];
>> +		entity = find_pipeline_entity(imxmd, graph, start_entity, id);
>> +		if (!entity)
>> +			continue;
>> +
>> +		sd = media_entity_to_v4l2_subdev(entity);
>> +
>> +		ret = v4l2_subdev_call(sd, core, s_power, on);
>> +		if (ret && ret != -ENOIOCTLCMD)
>> +			break;
>> +	}
>> +
>> +	return (ret && ret != -ENOIOCTLCMD) ? ret : 0;
>> +}
>> +EXPORT_SYMBOL_GPL(imx_media_pipeline_set_power);
> This should really be handled by v4l2_pipeline_pm_use.

I thought about this earlier, but v4l2_pipeline_pm_use() seems to be
doing some other stuff that bothered me, at least that's what I remember.
I will revisit this.

>> +/*
>> + * Inherit the v4l2 controls from all entities in a pipeline
>> + * to the given video device.
>> + * Must be called with mdev->graph_mutex held.
>> + */
>> +int imx_media_inherit_controls(struct imx_media_dev *imxmd,
>> +			       struct video_device *vfd,
>> +			       struct media_entity *start_entity)
>> +{
>> +	struct media_entity_graph graph;
>> +	struct media_entity *entity;
>> +	struct v4l2_subdev *sd;
>> +	int ret;
>> +
>> +	ret = media_entity_graph_walk_init(&graph, &imxmd->md);
>> +	if (ret)
>> +		return ret;
>> +
>> +	media_entity_graph_walk_start(&graph, start_entity);
>> +
>> +	while ((entity = media_entity_graph_walk_next(&graph))) {
>> +		if (is_media_entity_v4l2_video_device(entity))
>> +			continue;
>> +
>> +		sd = media_entity_to_v4l2_subdev(entity);
>> +
>> +		dev_dbg(imxmd->dev, "%s: adding controls from %s\n",
>> +			__func__, sd->name);
>> +
>> +		ret = v4l2_ctrl_add_handler(vfd->ctrl_handler,
>> +					    sd->ctrl_handler,
>> +					    NULL);
>> +		if (ret)
>> +			break;
>> +	}
>> +
>> +	media_entity_graph_walk_cleanup(&graph);
>> +	return ret;
>> +}
>> +EXPORT_SYMBOL_GPL(imx_media_inherit_controls);
>> +
>> +MODULE_DESCRIPTION("i.MX5/6 v4l2 media controller driver");
>> +MODULE_AUTHOR("Steve Longerbeam<steve_longerbeam@mentor.com>");
>> +MODULE_LICENSE("GPL");
>> diff --git a/drivers/staging/media/imx/imx-media-dev.c b/drivers/staging/media/imx/imx-media-dev.c
>> new file mode 100644
>> index 0000000..357654d
>> --- /dev/null
>> +++ b/drivers/staging/media/imx/imx-media-dev.c
> This file is full of code that should live in the v4l2 core.

Agreed. Stuff like imx_media_inherit_controls() really should be widely
available.

>> +int imx_media_add_internal_subdevs(struct imx_media_dev *imxmd,
>> +				   struct imx_media_subdev *csi[4])
>> +{
>> +	int ret;
>> +
>> +	/* there must be at least one CSI in first IPU */
> Why?

Well yeah, imx-media doesn't necessarily need a CSI if things
like the VDIC or post-processor are being used by an output
overlay pipeline, for example. I'll fix this.

>> +
>> +/* parse inputs property from a sensor node */
>> +static void of_parse_sensor_inputs(struct imx_media_dev *imxmd,
>> +				   struct imx_media_subdev *sensor,
>> +				   struct device_node *sensor_np)
>> +{
>> +	struct imx_media_sensor_input *sinput = &sensor->input;
>> +	int ret, i;
>> +
>> +	for (i = 0; i < IMX_MEDIA_MAX_SENSOR_INPUTS; i++) {
>> +		const char *input_name;
>> +		u32 val;
>> +
>> +		ret = of_property_read_u32_index(sensor_np, "inputs", i, &val);
>> +		if (ret)
>> +			break;
>> +
>> +		sinput->value[i] = val;
>> +
>> +		ret = of_property_read_string_index(sensor_np, "input-names",
>> +						    i, &input_name);
>> +		/*
>> +		 * if input-names not provided, they will be set using
>> +		 * the subdev name once the sensor is known during
>> +		 * async bind
>> +		 */
>> +		if (!ret)
>> +			strncpy(sinput->name[i], input_name,
>> +				sizeof(sinput->name[i]));
>> +	}
>> +
>> +	sinput->num = i;
>> +
>> +	/* if no inputs provided just assume a single input */
>> +	if (sinput->num == 0)
>> +		sinput->num = 1;
>> +}
> This should be parsed by the sensor driver, not imx-media.

you're probably right. I'll submit a patch for adv7180.c.


>> +static void of_parse_sensor(struct imx_media_dev *imxmd,
>> +			    struct imx_media_subdev *sensor,
>> +			    struct device_node *sensor_np)
>> +{
>> +	struct device_node *endpoint;
>> +
>> +	of_parse_sensor_inputs(imxmd, sensor, sensor_np);
>> +
>> +	endpoint = of_graph_get_next_endpoint(sensor_np, NULL);
>> +	if (endpoint) {
>> +		v4l2_of_parse_endpoint(endpoint, &sensor->sensor_ep);
>> +		of_node_put(endpoint);
>> +	}
>> +}
>> +
>> +static int of_get_port_count(const struct device_node *np)
>> +{
>> +	struct device_node *child;
>> +	int num = 0;
>> +
>> +	/* if this node is itself a port, return 1 */
>> +	if (of_node_cmp(np->name, "port") == 0)
>> +		return 1;
>> +
>> +	for_each_child_of_node(np, child)
>> +		if (of_node_cmp(child->name, "port") == 0)
>> +			num++;
>> +
>> +	return num;
>> +}
> If this is extended to handle the ports subnode properly, it could be
> moved into drivers/of/base.c.

More that eventually needs exporting, agreed.


Steve

^ permalink raw reply

* Nokia N900: mixers changed between 4.9 and 4.10-rc3, no longer can use in-call speaker
From: Pavel Machek @ 2017-01-14 22:56 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <201701121934.19810@pali>

Hi!

> > In v4.10 (and probably v4.9, too) I can no longer use the in-call
> > speaker. I can no longer use the wired headset, either.
> > 
> > v4.4 (and probably v4.6) works ok.
> > 
> > Any ideas? Does wired headset / in-call speaker work for you?
> > 
> > "Mono" and "Mono DAC" options are still there.. but something else
> > changed, as alsamixer now shows way many more options (meaning they
> > are shorter?) and I get complains from alsactl:
> > 
> > alsactl: set_control:1328: failed to obtain info for control #49 (No
> > such file or directory)
> > ...
> > alsactl: set_control:1328: failed to obtain info for control #229 (No
> > such file or directory)
> 
> Looks like there are not so much commits related to 
> sound/soc/omap/rx51.c Maybe it can be one of these twos?
> 
> cb7e62256e99d285e415cf75db67558f0f8bb107
> 6d2de5ab4328718302c54b20222c6b1a574c3fce

Both are based on v4.7-rc1. v4.6 worked ok for me.

Lets test mini-v4.7: in-call speaker works ok there, and no alsactl
warnings.

mini-v4.7+cb7e62256e99d285e415cf75db67558f0f8bb107+6d2de5ab4328718302c54b20222c6b1a574c3fce
: something seems to be broken there already.

alsactl: set_control:1464: Cannot write control '2:0:0:TPA6130A2
Headphone Playback Volume:0' : Remote I/O error

But in-call speakers and wired headset still seems to work.

Lets test mini-v4.9... works ok. I don't even get the remote i/o
error. Interesting.

So regression seems to be between v4.9 and v4.10. Any ideas?

								Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20170114/3faf5c9e/attachment.sig>

^ permalink raw reply

* Nokia N900: mixers changed between 4.9 and 4.10-rc3, no longer can use in-call speaker
From: Pali Rohár @ 2017-01-15  0:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170114225614.GA25321@amd>

On Saturday 14 January 2017 23:56:15 Pavel Machek wrote:
> Hi!
> 
> > > In v4.10 (and probably v4.9, too) I can no longer use the in-call
> > > speaker. I can no longer use the wired headset, either.
> > > 
> > > v4.4 (and probably v4.6) works ok.
> > > 
> > > Any ideas? Does wired headset / in-call speaker work for you?
> > > 
> > > "Mono" and "Mono DAC" options are still there.. but something
> > > else changed, as alsamixer now shows way many more options
> > > (meaning they are shorter?) and I get complains from alsactl:
> > > 
> > > alsactl: set_control:1328: failed to obtain info for control #49
> > > (No such file or directory)
> > > ...
> > > alsactl: set_control:1328: failed to obtain info for control #229
> > > (No such file or directory)
> > 
> > Looks like there are not so much commits related to
> > sound/soc/omap/rx51.c Maybe it can be one of these twos?
> > 
> > cb7e62256e99d285e415cf75db67558f0f8bb107
> > 6d2de5ab4328718302c54b20222c6b1a574c3fce
> 
> Both are based on v4.7-rc1. v4.6 worked ok for me.
> 
> Lets test mini-v4.7: in-call speaker works ok there, and no alsactl
> warnings.
> 
> mini-v4.7+cb7e62256e99d285e415cf75db67558f0f8bb107+6d2de5ab4328718302
> c54b20222c6b1a574c3fce
> 
> : something seems to be broken there already.
> 
> alsactl: set_control:1464: Cannot write control '2:0:0:TPA6130A2
> Headphone Playback Volume:0' : Remote I/O error
> 
> But in-call speakers and wired headset still seems to work.
> 
> Lets test mini-v4.9... works ok. I don't even get the remote i/o
> error. Interesting.
> 
> So regression seems to be between v4.9 and v4.10. Any ideas?

Interesting... seems there are no sound relevant changes after v4.9.

Looks like there are only three commits after v4.9 for sound/soc which 
are built for Nokia N900:

e411b0b5eb9b65257a050eac333d181d6e00e2c6
e7aa450fe17890e59db7d3c2d8eff5b6b41fc531
63c3194b82530bd71fd49db84eb7ab656b8d404a

Maybe something not related to sound/soc could broke it?

-- 
Pali Roh?r
pali.rohar at gmail.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20170115/1ff353d6/attachment.sig>

^ permalink raw reply

* [PATCH v3] ARM: dts: Add LEGO MINDSTORMS EV3 dts
From: kbuild test robot @ 2017-01-15  0:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484253167-27568-1-git-send-email-david@lechnology.com>

Hi David,

[auto build test ERROR on robh/for-next]
[also build test ERROR on v4.10-rc3 next-20170113]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/David-Lechner/ARM-dts-Add-LEGO-MINDSTORMS-EV3-dts/20170114-145113
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
config: arm-u300_defconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (Debian 6.1.1-9) 6.1.1 20160705
reproduce:
        wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=arm 

All errors (new ones prefixed by >>):

>> Error: arch/arm/boot/dts/da850-lego-ev3.dts:310.1-6 Label or path usb1 not found
   FATAL ERROR: Syntax error parsing input tree

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 12462 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20170115/a5b32497/attachment-0001.gz>

^ permalink raw reply

* [PATCH v1 2/2] arm: dts: mt2701: add nor flash node
From: Marek Vasut @ 2017-01-15  0:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170114092958.022f2fc8@bbrezillon>

On 01/14/2017 09:29 AM, Boris Brezillon wrote:
> On Fri, 13 Jan 2017 18:33:40 +0100
> Marek Vasut <marek.vasut@gmail.com> wrote:
> 
>> On 01/13/2017 05:56 PM, Boris Brezillon wrote:
>>> On Fri, 13 Jan 2017 17:44:12 +0100
>>> Marek Vasut <marek.vasut@gmail.com> wrote:
>>>   
>>>> On 01/13/2017 05:28 PM, Boris Brezillon wrote:  
>>>>> On Fri, 13 Jan 2017 17:13:55 +0100
>>>>> Marek Vasut <marek.vasut@gmail.com> wrote:
>>>>>     
>>>>>> On 01/13/2017 04:12 PM, Matthias Brugger wrote:    
>>>>>>>
>>>>>>>
>>>>>>> On 13/01/17 15:17, Boris Brezillon wrote:      
>>>>>>>> On Fri, 13 Jan 2017 15:13:29 +0800
>>>>>>>> Guochun Mao <guochun.mao@mediatek.com> wrote:
>>>>>>>>      
>>>>>>>>> Add Mediatek nor flash node.
>>>>>>>>>
>>>>>>>>> Signed-off-by: Guochun Mao <guochun.mao@mediatek.com>
>>>>>>>>> ---
>>>>>>>>>  arch/arm/boot/dts/mt2701-evb.dts |   25 +++++++++++++++++++++++++
>>>>>>>>>  arch/arm/boot/dts/mt2701.dtsi    |   12 ++++++++++++
>>>>>>>>>  2 files changed, 37 insertions(+)
>>>>>>>>>
>>>>>>>>> diff --git a/arch/arm/boot/dts/mt2701-evb.dts
>>>>>>>>> b/arch/arm/boot/dts/mt2701-evb.dts
>>>>>>>>> index 082ca88..85e5ae8 100644
>>>>>>>>> --- a/arch/arm/boot/dts/mt2701-evb.dts
>>>>>>>>> +++ b/arch/arm/boot/dts/mt2701-evb.dts
>>>>>>>>> @@ -24,6 +24,31 @@
>>>>>>>>>      };
>>>>>>>>>  };
>>>>>>>>>
>>>>>>>>> +&nor_flash {
>>>>>>>>> +    pinctrl-names = "default";
>>>>>>>>> +    pinctrl-0 = <&nor_pins_default>;
>>>>>>>>> +    status = "okay";
>>>>>>>>> +    flash at 0 {
>>>>>>>>> +        compatible = "jedec,spi-nor";
>>>>>>>>> +        reg = <0>;
>>>>>>>>> +    };
>>>>>>>>> +};
>>>>>>>>> +
>>>>>>>>> +&pio {
>>>>>>>>> +    nor_pins_default: nor {
>>>>>>>>> +        pins1 {
>>>>>>>>> +            pinmux = <MT2701_PIN_240_EXT_XCS__FUNC_EXT_XCS>,
>>>>>>>>> +                 <MT2701_PIN_241_EXT_SCK__FUNC_EXT_SCK>,
>>>>>>>>> +                 <MT2701_PIN_239_EXT_SDIO0__FUNC_EXT_SDIO0>,
>>>>>>>>> +                 <MT2701_PIN_238_EXT_SDIO1__FUNC_EXT_SDIO1>,
>>>>>>>>> +                 <MT2701_PIN_237_EXT_SDIO2__FUNC_EXT_SDIO2>,
>>>>>>>>> +                 <MT2701_PIN_236_EXT_SDIO3__FUNC_EXT_SDIO3>;
>>>>>>>>> +            drive-strength = <MTK_DRIVE_4mA>;
>>>>>>>>> +            bias-pull-up;
>>>>>>>>> +        };
>>>>>>>>> +    };
>>>>>>>>> +};
>>>>>>>>> +
>>>>>>>>>  &uart0 {
>>>>>>>>>      status = "okay";
>>>>>>>>>  };
>>>>>>>>> diff --git a/arch/arm/boot/dts/mt2701.dtsi
>>>>>>>>> b/arch/arm/boot/dts/mt2701.dtsi
>>>>>>>>> index bdf8954..1eefce4 100644
>>>>>>>>> --- a/arch/arm/boot/dts/mt2701.dtsi
>>>>>>>>> +++ b/arch/arm/boot/dts/mt2701.dtsi
>>>>>>>>> @@ -227,6 +227,18 @@
>>>>>>>>>          status = "disabled";
>>>>>>>>>      };
>>>>>>>>>
>>>>>>>>> +    nor_flash: spi at 11014000 {
>>>>>>>>> +        compatible = "mediatek,mt2701-nor",
>>>>>>>>> +                 "mediatek,mt8173-nor";      
>>>>>>>>
>>>>>>>> Why define both here? Is "mediatek,mt8173-nor" really providing a
>>>>>>>> subset of the features supported by "mediatek,mt2701-nor"?
>>>>>>>>      
>>>>>>>
>>>>>>> I think even if the ip block is the same, we should provide both
>>>>>>> bindings, just in case in the future we find out that mt2701 has some
>>>>>>> hidden bug, feature or bug-feature. This way even if we update the
>>>>>>> driver, we stay compatible with older device tree blobs in the wild.
>>>>>>>
>>>>>>> We can drop the mt2701-nor in the bindings definition if you want.     
>>>>>
>>>>> Oh, sorry, I misunderstood. What I meant is that if you want to
>>>>> list/support all possible compatibles, maybe you should just put one
>>>>> compatible in your DT and patch your driver (+ binding doc) to define
>>>>> all of them.    
>>>>
>>>> Uh, what ? I lost you here :-)
> 
> I mean adding a new entry in the mtk_nor_of_ids table (in
> mtk-quadspi.c) so that the mediatek,mt2701-nor compatible string can be
> matched directly, and you won't need to define 2 compatible strings in
> your device tree.

But then you grow the table in the driver, is that what we want if we
can avoid that ?

>>>>  
>>>>>> This exactly. We should have a DT compat in the form:
>>>>>> compatible = "vendor,<soc>-block", "vendor,<oldest-compat-soc>-block";
>>>>>> Then if we find a problem in the future, we can match on the
>>>>>> "vendor,<soc>-block" and still support the old DTs.    
>>>>>
>>>>> Not sure it's only in term of whose IP appeared first. My understanding
>>>>> is that it's a way to provide inheritance. For example:
>>>>>
>>>>> 	"<soc-vendor>,<ip-version>", "<ip-vendor>,<ip-version>";
>>>>>
>>>>> or
>>>>>
>>>>> 	"<soc-vendor>,<full-featured-ip-version>","<soc-vendor>,<basic-feature-ip-version>";
>>>>>
>>>>> BTW, which one is the oldest between mt8173 and mt2701? :-)    
>>>>
>>>> And that's another thing and I agree with you, but I don't think that's
>>>> what we're discussing in this thread. But (!), OT, I think we should
>>>> codify the rules in Documentation/ . This discussion came up multiple
>>>> times recently.
>>>>
>>>> And my question still stands, what do we put into the DT here, IMO
>>>> compatible = "mediatek,mt2701-nor", "mediatek,mt8173-nor";  
>>>
>>> I'd say
>>>
>>> 	compatible = "mediatek,mt8173-nor";
>>>
>>> because both compatible are referring to very specific IP version. It's
>>> not the same as  
>>
>> But then you don't have the ability to handle a block in this particular
>> SoC in case there's a bug found in it in the future,
>> so IMO it should be:
>>
>> compatible = "mediatek,mt2701-nor", "mediatek,mt8173-nor";
> 
> Sorry again, I meant
> 
> 	compatible = "mediatek,mt2701-nor";
> 
>>
>>> 	compatible = "mediatek,mt8173-nor", "mediatek,mt81xx-nor";  
>>
>> This doesn't look right, since here we add two new compatibles ...
> 
> That was just an example to describe how compatible inheritance works
> (at least that's my understanding of it), it does not apply to this
> particular use case.

Well this is OK I guess, but then you can also use "mediatek,mt8173-nor"
as the oldest supported compatible and be done with it, no ? It looks a
bit crappy though, I admit that ...

-- 
Best regards,
Marek Vasut

^ permalink raw reply

* [PATCH 0/4] Drop drivers for Exynos4415
From: Kukjin Kim @ 2017-01-15  2:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170114123642.15581-1-krzk@kernel.org>

Hi Krzk,

2017. 1. 14. PM 8:36 Krzysztof Kozlowski <krzk@kernel.org> wrote:

> Hi,
> 
> Support for Exynos4415 is being removed because:
> 1. There are no upstream users,
> 2. There are no known downstream users,
> 3. Except compile testing, you cannot build working kernel
>   for Exynos4415 anymore.
> 
> Patches are rebased on current next and are independent.
> Please pick up as you wish.
> 
> Best regards,
> Krzysztof

Agreed,

Acked-by: Kukjin Kim <kgene@kernel.org>

k-gene
> 
> Krzysztof Kozlowski (4):
>  ARM: EXYNOS: Remove Exynos4415 driver (SoC not supported anymore)
>  clk: samsung: Remove Exynos4415 driver (SoC not supported anymore)
>  pinctrl: samsung: Remove support for Exynos4415 (SoC not supported
>    anymore)
>  drm: exynos: Remove support for Exynos4415 (SoC not supported anymore)
> 
> .../devicetree/bindings/clock/exynos4415-clock.txt |   38 -
> .../bindings/display/exynos/exynos_dsim.txt        |    1 -
> .../bindings/display/exynos/samsung-fimd.txt       |    1 -
> arch/arm/mach-exynos/Kconfig                       |    5 -
> arch/arm/mach-exynos/exynos.c                      |    1 -
> arch/arm/mach-exynos/suspend.c                     |    1 -
> drivers/clk/samsung/Makefile                       |    1 -
> drivers/clk/samsung/clk-exynos4415.c               | 1022 --------------------
> drivers/gpu/drm/exynos/exynos_drm_dsi.c            |   15 +-
> drivers/gpu/drm/exynos/exynos_drm_fimd.c           |   18 +-
> drivers/pinctrl/samsung/pinctrl-exynos.c           |   75 --
> drivers/pinctrl/samsung/pinctrl-samsung.c          |    2 -
> drivers/pinctrl/samsung/pinctrl-samsung.h          |    1 -
> include/dt-bindings/clock/exynos4415.h             |  360 -------
> 14 files changed, 3 insertions(+), 1538 deletions(-)
> delete mode 100644 Documentation/devicetree/bindings/clock/exynos4415-clock.txt
> delete mode 100644 drivers/clk/samsung/clk-exynos4415.c
> delete mode 100644 include/dt-bindings/clock/exynos4415.h
> 
> -- 
> 2.9.3
> 

^ permalink raw reply

* [PATCH RFC v2 4/4] ARM: dts: imx6*-hummingboard2: convert to more conventional vmmc-supply
From: Fabio Estevam @ 2017-01-15  2:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <E1cS36q-0002wW-C3@rmk-PC.armlinux.org.uk>

On Fri, Jan 13, 2017 at 12:45 PM, Russell King
<rmk+kernel@arm.linux.org.uk> wrote:

> +       reg_usdhc2_vmmc: reg-usdhc2-vmmc {
> +               compatible = "regulator-fixed";
> +               gpio = <&gpio4 30 GPIO_ACTIVE_HIGH>;
> +               pinctrl-names = "default";
> +               pinctrl-0 = <&pinctrl_hummingboard2_vmmc>;
> +               regulator-boot-on;
> +               regulator-max-microvolt = <3300000>;
> +               regulator-min-microvolt = <3300000>;
> +               regulator-name = "usdhc2_vmmc";
> +               startup-delay-us = <1000>;
> +       };
> +
>         sound-sgtl5000 {
>                 audio-codec = <&sgtl5000>;
>                 audio-routing =
> @@ -393,7 +400,6 @@
>
>                 pinctrl_hummingboard2_usdhc2_aux: hummingboard2-usdhc2-aux {
>                         fsl,pins = <
> -                               MX6QDL_PAD_GPIO_4__GPIO1_IO04    0x1f071
>                                 MX6QDL_PAD_KEY_ROW1__SD2_VSELECT 0x1b071
>                                 MX6QDL_PAD_DISP0_DAT9__GPIO4_IO30 0x1b0b0
>                         >;
> @@ -432,6 +438,12 @@
>                         >;
>                 };
>
> +               pinctrl_hummingboard2_vmmc: hummingboard2-vmmc {
> +                       fsl,pins = <
> +                               MX6QDL_PAD_GPIO_4__GPIO1_IO04    0x1f071

Shouldn't this be gpio4 30 instead?

> +                       >;
> +               };
> +
>                 pinctrl_hummingboard2_usdhc3: hummingboard2-usdhc3 {
>                         fsl,pins = <
>                                 MX6QDL_PAD_SD3_CMD__SD3_CMD    0x17059
> @@ -519,7 +531,7 @@
>                 &pinctrl_hummingboard2_usdhc2_aux
>                 &pinctrl_hummingboard2_usdhc2_200mhz
>         >;
> -       mmc-pwrseq = <&usdhc2_pwrseq>;
> +       vmmc-supply = <&reg_usdhc2_vmmc>;
>         cd-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;

as gpio1 4 seems to be used as card detect.

^ permalink raw reply

* [PATCH 1/2] ARM: BCM5301X: Add DT for Luxul XAP-1410
From: Dan Haab @ 2017-01-15  2:29 UTC (permalink / raw)
  To: linux-arm-kernel

Luxul XAP-1410 in a dual-band access point device based on BCM47081 with
serial flash. It has 3 LEDs and just one (reset) button.

Signed-off-by: Dan Haab <dhaab@luxul.com>
---
 arch/arm/boot/dts/Makefile                    |    1 +
 arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts |   60 +++++++++++++++++++++++++
 2 files changed, 61 insertions(+)
 create mode 100644 arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index cccdbcb..04fd8f0 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -83,6 +83,7 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \
 	bcm47081-asus-rt-n18u.dtb \
 	bcm47081-buffalo-wzr-600dhp2.dtb \
 	bcm47081-buffalo-wzr-900dhp.dtb \
+	bcm47081-luxul-xap-1410.dtb \
 	bcm4709-asus-rt-ac87u.dtb \
 	bcm4709-buffalo-wxr-1900dhp.dtb \
 	bcm4709-netgear-r7000.dtb \
diff --git a/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts b/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
new file mode 100644
index 0000000..9b57598
--- /dev/null
+++ b/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2017 Luxul Inc.
+ *
+ * Licensed under the ISC license.
+ */
+
+/dts-v1/;
+
+#include "bcm47081.dtsi"
+
+/ {
+	compatible = "luxul,xap-1410v1", "brcm,bcm47081", "brcm,bcm4708";
+	model = "Luxul XAP-1410 V1";
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	memory {
+		reg = <0x00000000 0x08000000>;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		5ghz {
+			label = "bcm53xx:blue:5ghz";
+			gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "none";
+		};
+
+		2ghz {
+			label = "bcm53xx:blue:2ghz";
+			gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "none";
+		};
+
+		status {
+			label = "bcm53xx:green:status";
+			gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "timer";
+		};
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		restart {
+			label = "Reset";
+			linux,code = <KEY_RESTART>;
+			gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&spi_nor {
+	status = "okay";
+};
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 2/2] ARM: BCM5301X: Add DT for Luxul XWR-1200
From: Dan Haab @ 2017-01-15  2:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484447368-7622-1-git-send-email-dhaab@luxul.com>

Luxul XWR-1200 in a dual-band router based on BCM47081. It uses serial
flash (for bootloader and NVRAM) and NAND flash (for firmware).

Signed-off-by: Dan Haab <dhaab@luxul.com>
---
 arch/arm/boot/dts/Makefile                    |    1 +
 arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts |  107 +++++++++++++++++++++++++
 2 files changed, 108 insertions(+)
 create mode 100644 arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 04fd8f0..8a403a2 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -84,6 +84,7 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \
 	bcm47081-buffalo-wzr-600dhp2.dtb \
 	bcm47081-buffalo-wzr-900dhp.dtb \
 	bcm47081-luxul-xap-1410.dtb \
+	bcm47081-luxul-xwr-1200.dtb \
 	bcm4709-asus-rt-ac87u.dtb \
 	bcm4709-buffalo-wxr-1900dhp.dtb \
 	bcm4709-netgear-r7000.dtb \
diff --git a/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts b/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
new file mode 100644
index 0000000..c544ab3
--- /dev/null
+++ b/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2017 Luxul Inc.
+ *
+ * Licensed under the ISC license.
+ */
+
+/dts-v1/;
+
+#include "bcm47081.dtsi"
+#include "bcm5301x-nand-cs0-bch4.dtsi"
+
+/ {
+	compatible = "luxul,xwr-1200v1", "brcm,bcm47081", "brcm,bcm4708";
+	model = "Luxul XWR-1200 V1";
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	memory {
+		reg = <0x00000000 0x08000000>;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		power {
+			label = "bcm53xx:green:power";
+			gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "default-on";
+		};
+
+		lan3 {
+			label = "bcm53xx:green:lan3";
+			gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "none";
+		};
+
+		lan4 {
+			label = "bcm53xx:green:lan4";
+			gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "none";
+		};
+
+		wan {
+			label = "bcm53xx:green:wan";
+			gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "none";
+		};
+
+		lan2 {
+			label = "bcm53xx:green:lan2";
+			gpios = <&chipcommon 6 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "none";
+		};
+
+		usb {
+			label = "bcm53xx:green:usb";
+			gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "none";
+		};
+
+		status {
+			label = "bcm53xx:green:status";
+			gpios = <&chipcommon 10 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "timer";
+		};
+
+		2ghz {
+			label = "bcm53xx:green:2ghz";
+			gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "none";
+		};
+
+		5ghz {
+			label = "bcm53xx:green:5ghz";
+			gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "none";
+		};
+
+		lan1 {
+			label = "bcm53xx:green:lan1";
+			gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "none";
+		};
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		restart {
+			label = "Reset";
+			linux,code = <KEY_RESTART>;
+			gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&usb2 {
+	vcc-gpio = <&chipcommon 9 GPIO_ACTIVE_HIGH>;
+};
+
+&spi_nor {
+	status = "okay";
+};
-- 
1.7.9.5

^ permalink raw reply related

* [GIT PULL 2/2] Broadcom defconfig fixes for 4.10
From: Florian Fainelli @ 2017-01-15  2:36 UTC (permalink / raw)
  To: linux-arm-kernel

The following changes since commit 7ce7d89f48834cefece7804d38fc5d85382edf77:

  Linux 4.10-rc1 (2016-12-25 16:13:08 -0800)

are available in the git repository at:

  http://github.com/Broadcom/stblinux.git tags/arm-soc/for-4.10/defconfig-fixes

for you to fetch changes up to 91546c56624a79f4a8fd80bede6b5a38c0f0ad78:

  ARM: multi_v7_defconfig: set bcm47xx watchdog (2017-01-12 16:03:12 -0800)

----------------------------------------------------------------
This pull request contains fixes to multi_v7_defconfig for Broadcom ARM-based
SoCs, please pull the following changes:

- Valenting fixes two incorrect Kconfig symbols for BCM47xx: NVRAM and watchdog drivers

----------------------------------------------------------------
Valentin Rothberg (2):
      ARM: multi_v7_defconfig: fix config typo
      ARM: multi_v7_defconfig: set bcm47xx watchdog

 arch/arm/configs/multi_v7_defconfig | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

^ permalink raw reply

* [GIT PULL 1/2] Broadcom arm Device Tree fixes for 4.10
From: Florian Fainelli @ 2017-01-15  2:36 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170115023637.24759-1-f.fainelli@gmail.com>

The following changes since commit 7ce7d89f48834cefece7804d38fc5d85382edf77:

  Linux 4.10-rc1 (2016-12-25 16:13:08 -0800)

are available in the git repository at:

  http://github.com/Broadcom/stblinux.git tags/arm-soc/for-4.10/devicetree-fixes

for you to fetch changes up to 6771e01f7965ea13988d0a5a7972f97be4e46452:

  ARM: dts: NSP: Fix DT ranges error (2017-01-12 16:07:27 -0800)

----------------------------------------------------------------
This pull request contains Broadcom ARM-based SoC Device Tree fixes for v4.10, please
pull the following:

- Jon fixes an invalid value for the "ranges" property of the bus nodes on NorthStar
  Plus SoCs

----------------------------------------------------------------
Jon Mason (1):
      ARM: dts: NSP: Fix DT ranges error

 arch/arm/boot/dts/bcm-nsp.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

^ permalink raw reply

* [PATCH v6 0/4] ARM: Add support for CONFIG_DEBUG_VIRTUAL
From: Florian Fainelli @ 2017-01-15  3:01 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170104223955.22859-1-f.fainelli@gmail.com>

Le 01/04/17 ? 14:39, Florian Fainelli a ?crit :
> This patch series builds on top of Laura's [PATCHv6 00/10] CONFIG_DEBUG_VIRTUAL
> for arm64 to add support for CONFIG_DEBUG_VIRTUAL for ARM.
> 
> This was tested on a Brahma B15 platform (ARMv7 + HIGHMEM + LPAE).
> 
> Note that the treewide changes would involve a huge CC list, which
> is why it has been purposely trimmed to just focusing on the DEBUG_VIRTUAL
> aspect.
> 
> Catalin, provided that you take Laura's series, I suppose I would submit
> this one through Russell's patch system if that's okay with everyone?

Submitted through Russell's patch tracking system as #8638-8641
-- 
Florian

^ permalink raw reply

* [PATCH v6 2/3] input: tm2-touchkey: Add touchkey driver support for TM2
From: Dmitry Torokhov @ 2017-01-15  7:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1483946535-4703-3-git-send-email-jcsing.lee@samsung.com>

Hi Jaechul,

On Mon, Jan 09, 2017 at 04:22:14PM +0900, Jaechul Lee wrote:
> +static irqreturn_t tm2_touchkey_irq_handler(int irq, void *devid)
> +{
> +	struct tm2_touchkey_data *touchkey = devid;
> +	u32 data;
> +
> +	data = i2c_smbus_read_byte_data(touchkey->client,
> +					TM2_TOUCHKEY_KEYCODE_REG);
> +
> +	if (data < 0) {

You declared data as u32 so it will never be negative.

> +		dev_err(&touchkey->client->dev, "Failed to read i2c data\n");
> +		return IRQ_HANDLED;
> +	}
> +
> +	touchkey->keycode_type = data & TM2_TOUCHKEY_BIT_KEYCODE;
> +	touchkey->pressed = !(data & TM2_TOUCHKEY_BIT_PRESS_EV);

There is no need to store this in touchkey structure as you are not
going to use it past this function.

Does the version of the patch below work for you?

Thanks.

-- 
Dmitry


Input: tm2-touchkey - add touchkey driver support for TM2

From: Jaechul Lee <jcsing.lee@samsung.com>

This patch adds support for the TM2 touch key and led functionality.

The driver interfaces with userspace through an input device and
reports KEY_PHONE and KEY_BACK event types. LED brightness can be
controlled by "/sys/class/leds/tm2-touchkey/brightness".

Signed-off-by: Beomho Seo <beomho.seo@samsung.com>
Signed-off-by: Jaechul Lee <jcsing.lee@samsung.com>
Reviewed-by: Javier Martinez Canillas <javier@osg.samsung.com>
Reviewed-by: Andi Shyti <andi.shyti@samsung.com>
Acked-by: Krzysztof Kozlowski <krzk@kernel.org>
Patchwork-Id: 9504149
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/keyboard/Kconfig        |   11 +
 drivers/input/keyboard/Makefile       |    1 
 drivers/input/keyboard/tm2-touchkey.c |  286 +++++++++++++++++++++++++++++++++
 3 files changed, 298 insertions(+)
 create mode 100644 drivers/input/keyboard/tm2-touchkey.c

diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index cbd75cf44739..97acd6524ad7 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -666,6 +666,17 @@ config KEYBOARD_TC3589X
 	  To compile this driver as a module, choose M here: the
 	  module will be called tc3589x-keypad.
 
+config KEYBOARD_TM2_TOUCHKEY
+	tristate "TM2 touchkey support"
+	depends on I2C
+	depends on LEDS_CLASS
+	help
+	  Say Y here to enable device driver for tm2-touchkey with
+	  LED control for the Exynos5433 TM2 board.
+
+	  To compile this driver as a module, choose M here.
+	  module will be called tm2-touchkey.
+
 config KEYBOARD_TWL4030
 	tristate "TI TWL4030/TWL5030/TPS659x0 keypad support"
 	depends on TWL4030_CORE
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index d9f4cfcf3410..7d9acff819a7 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -61,6 +61,7 @@ obj-$(CONFIG_KEYBOARD_SUN4I_LRADC)	+= sun4i-lradc-keys.o
 obj-$(CONFIG_KEYBOARD_SUNKBD)		+= sunkbd.o
 obj-$(CONFIG_KEYBOARD_TC3589X)		+= tc3589x-keypad.o
 obj-$(CONFIG_KEYBOARD_TEGRA)		+= tegra-kbc.o
+obj-$(CONFIG_KEYBOARD_TM2_TOUCHKEY)	+= tm2-touchkey.o
 obj-$(CONFIG_KEYBOARD_TWL4030)		+= twl4030_keypad.o
 obj-$(CONFIG_KEYBOARD_XTKBD)		+= xtkbd.o
 obj-$(CONFIG_KEYBOARD_W90P910)		+= w90p910_keypad.o
diff --git a/drivers/input/keyboard/tm2-touchkey.c b/drivers/input/keyboard/tm2-touchkey.c
new file mode 100644
index 000000000000..79bc2d2bd4b9
--- /dev/null
+++ b/drivers/input/keyboard/tm2-touchkey.c
@@ -0,0 +1,286 @@
+/*
+ * TM2 touchkey device driver
+ *
+ * Copyright 2005 Phil Blundell
+ * Copyright 2016 Samsung Electronics Co., Ltd.
+ *
+ * Author: Beomho Seo <beomho.seo@samsung.com>
+ * Author: Jaechul Lee <jcsing.lee@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/leds.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/pm.h>
+#include <linux/regulator/consumer.h>
+
+#define TM2_TOUCHKEY_DEV_NAME		"tm2-touchkey"
+#define TM2_TOUCHKEY_KEYCODE_REG	0x03
+#define TM2_TOUCHKEY_BASE_REG		0x00
+#define TM2_TOUCHKEY_CMD_LED_ON		0x10
+#define TM2_TOUCHKEY_CMD_LED_OFF	0x20
+#define TM2_TOUCHKEY_BIT_PRESS_EV	BIT(3)
+#define TM2_TOUCHKEY_BIT_KEYCODE	GENMASK(2, 0)
+#define TM2_TOUCHKEY_LED_VOLTAGE_MIN	2500000
+#define TM2_TOUCHKEY_LED_VOLTAGE_MAX	3300000
+
+enum {
+	TM2_TOUCHKEY_KEY_MENU = 0x1,
+	TM2_TOUCHKEY_KEY_BACK,
+};
+
+struct tm2_touchkey_data {
+	struct i2c_client *client;
+	struct input_dev *input_dev;
+	struct led_classdev led_dev;
+	struct regulator *vdd;
+	struct regulator_bulk_data regulators[2];
+};
+
+static void tm2_touchkey_led_brightness_set(struct led_classdev *led_dev,
+					    enum led_brightness brightness)
+{
+	struct tm2_touchkey_data *touchkey =
+		container_of(led_dev, struct tm2_touchkey_data, led_dev);
+	u32 volt;
+	u8 data;
+
+	if (brightness == LED_OFF) {
+		volt = TM2_TOUCHKEY_LED_VOLTAGE_MIN;
+		data = TM2_TOUCHKEY_CMD_LED_OFF;
+	} else {
+		volt = TM2_TOUCHKEY_LED_VOLTAGE_MAX;
+		data = TM2_TOUCHKEY_CMD_LED_ON;
+	}
+
+	regulator_set_voltage(touchkey->vdd, volt, volt);
+	i2c_smbus_write_byte_data(touchkey->client,
+				  TM2_TOUCHKEY_BASE_REG, data);
+}
+
+static int tm2_touchkey_power_enable(struct tm2_touchkey_data *touchkey)
+{
+	int error;
+
+	error = regulator_bulk_enable(ARRAY_SIZE(touchkey->regulators),
+				      touchkey->regulators);
+	if (error)
+		return error;
+
+	/* waiting for device initialization, at least 150ms */
+	msleep(150);
+
+	return 0;
+}
+
+static void tm2_touchkey_power_disable(void *data)
+{
+	struct tm2_touchkey_data *touchkey = data;
+
+	regulator_bulk_disable(ARRAY_SIZE(touchkey->regulators),
+			       touchkey->regulators);
+}
+
+static irqreturn_t tm2_touchkey_irq_handler(int irq, void *devid)
+{
+	struct tm2_touchkey_data *touchkey = devid;
+	int data;
+	int key;
+
+	data = i2c_smbus_read_byte_data(touchkey->client,
+					TM2_TOUCHKEY_KEYCODE_REG);
+	if (data < 0) {
+		dev_err(&touchkey->client->dev,
+			"failed to read i2c data: %d\n", data);
+		goto out;
+	}
+
+	switch (data & TM2_TOUCHKEY_BIT_KEYCODE) {
+	case TM2_TOUCHKEY_KEY_MENU:
+		key = KEY_PHONE;
+		break;
+
+	case TM2_TOUCHKEY_KEY_BACK:
+		key = KEY_BACK;
+		break;
+
+	default:
+		dev_warn(&touchkey->client->dev,
+			 "unhandled keycode, data %#02x\n", data);
+		goto out;
+	}
+
+	if (data & TM2_TOUCHKEY_BIT_PRESS_EV) {
+		input_report_key(touchkey->input_dev, key, 1);
+	} else {
+		input_report_key(touchkey->input_dev, KEY_PHONE, 0);
+		input_report_key(touchkey->input_dev, KEY_BACK, 0);
+	}
+
+	input_sync(touchkey->input_dev);
+
+out:
+	return IRQ_HANDLED;
+}
+
+static int tm2_touchkey_probe(struct i2c_client *client,
+			      const struct i2c_device_id *id)
+{
+	struct tm2_touchkey_data *touchkey;
+	int error;
+
+	if (!i2c_check_functionality(client->adapter,
+			I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA)) {
+		dev_err(&client->dev, "incompatible I2C adapter\n");
+		return -EIO;
+	}
+
+	touchkey = devm_kzalloc(&client->dev, sizeof(*touchkey), GFP_KERNEL);
+	if (!touchkey)
+		return -ENOMEM;
+
+	touchkey->client = client;
+	i2c_set_clientdata(client, touchkey);
+
+	touchkey->regulators[0].supply = "vcc";
+	touchkey->regulators[1].supply = "vdd";
+	error = devm_regulator_bulk_get(&client->dev,
+					ARRAY_SIZE(touchkey->regulators),
+					touchkey->regulators);
+	if (error) {
+		dev_err(&client->dev, "failed to get regulators: %d\n", error);
+		return error;
+	}
+
+	/* Save VDD for easy access */
+	touchkey->vdd = touchkey->regulators[1].consumer;
+
+	error = tm2_touchkey_power_enable(touchkey);
+	if (error) {
+		dev_err(&client->dev, "failed to power up device: %d\n", error);
+		return error;
+	}
+
+	error = devm_add_action_or_reset(&client->dev,
+					 tm2_touchkey_power_disable, touchkey);
+	if (error) {
+		dev_err(&client->dev,
+			"failed to install poweroff handler: %d\n", error);
+		return error;
+	}
+
+	/* input device */
+	touchkey->input_dev = devm_input_allocate_device(&client->dev);
+	if (!touchkey->input_dev) {
+		dev_err(&client->dev, "failed to allocate input device\n");
+		return -ENOMEM;
+	}
+
+	touchkey->input_dev->name = TM2_TOUCHKEY_DEV_NAME;
+	touchkey->input_dev->id.bustype = BUS_I2C;
+
+	input_set_capability(touchkey->input_dev, EV_KEY, KEY_PHONE);
+	input_set_capability(touchkey->input_dev, EV_KEY, KEY_BACK);
+
+	input_set_drvdata(touchkey->input_dev, touchkey);
+
+	error = input_register_device(touchkey->input_dev);
+	if (error) {
+		dev_err(&client->dev,
+			"failed to register input device: %d\n", error);
+		return error;
+	}
+
+	error = devm_request_threaded_irq(&client->dev, client->irq,
+					  NULL, tm2_touchkey_irq_handler,
+					  IRQF_ONESHOT,
+					  TM2_TOUCHKEY_DEV_NAME, touchkey);
+	if (error) {
+		dev_err(&client->dev,
+			"failed to request threaded irq: %d\n", error);
+		return error;
+	}
+
+	/* led device */
+	touchkey->led_dev.name = TM2_TOUCHKEY_DEV_NAME;
+	touchkey->led_dev.brightness = LED_FULL;
+	touchkey->led_dev.max_brightness = LED_FULL;
+	touchkey->led_dev.brightness_set = tm2_touchkey_led_brightness_set;
+
+	error = devm_led_classdev_register(&client->dev, &touchkey->led_dev);
+	if (error) {
+		dev_err(&client->dev,
+			"failed to register touchkey led: %d\n", error);
+		return error;
+	}
+
+	return 0;
+}
+
+static int __maybe_unused tm2_touchkey_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct tm2_touchkey_data *touchkey = i2c_get_clientdata(client);
+
+	disable_irq(client->irq);
+	tm2_touchkey_power_disable(touchkey);
+
+	return 0;
+}
+
+static int __maybe_unused tm2_touchkey_resume(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct tm2_touchkey_data *touchkey = i2c_get_clientdata(client);
+	int ret;
+
+	enable_irq(client->irq);
+
+	ret = tm2_touchkey_power_enable(touchkey);
+	if (ret)
+		dev_err(dev, "failed to enable power: %d\n", ret);
+
+	return ret;
+}
+
+static SIMPLE_DEV_PM_OPS(tm2_touchkey_pm_ops,
+			 tm2_touchkey_suspend, tm2_touchkey_resume);
+
+static const struct i2c_device_id tm2_touchkey_id_table[] = {
+	{ TM2_TOUCHKEY_DEV_NAME, 0 },
+	{ },
+};
+MODULE_DEVICE_TABLE(i2c, tm2_touchkey_id_table);
+
+static const struct of_device_id tm2_touchkey_of_match[] = {
+	{ .compatible = "cypress,tm2-touchkey", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, tm2_touchkey_of_match);
+
+static struct i2c_driver tm2_touchkey_driver = {
+	.driver = {
+		.name = TM2_TOUCHKEY_DEV_NAME,
+		.pm = &tm2_touchkey_pm_ops,
+		.of_match_table = of_match_ptr(tm2_touchkey_of_match),
+	},
+	.probe = tm2_touchkey_probe,
+	.id_table = tm2_touchkey_id_table,
+};
+module_i2c_driver(tm2_touchkey_driver);
+
+MODULE_AUTHOR("Beomho Seo <beomho.seo@samsung.com>");
+MODULE_AUTHOR("Jaechul Lee <jcsing.lee@samsung.com>");
+MODULE_DESCRIPTION("Samsung touchkey driver");
+MODULE_LICENSE("GPL v2");

^ permalink raw reply related

* Nokia N900: mixers changed between 4.9 and 4.10-rc3, no longer can use in-call speaker
From: Pavel Machek @ 2017-01-15 10:05 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <201701150100.54214@pali>

Hi!

> > Both are based on v4.7-rc1. v4.6 worked ok for me.
> > 
> > Lets test mini-v4.7: in-call speaker works ok there, and no alsactl
> > warnings.
> > 
> > mini-v4.7+cb7e62256e99d285e415cf75db67558f0f8bb107+6d2de5ab4328718302
> > c54b20222c6b1a574c3fce
> > 
> > : something seems to be broken there already.
> > 
> > alsactl: set_control:1464: Cannot write control '2:0:0:TPA6130A2
> > Headphone Playback Volume:0' : Remote I/O error
> > 
> > But in-call speakers and wired headset still seems to work.
> > 
> > Lets test mini-v4.9... works ok. I don't even get the remote i/o
> > error. Interesting.
> > 
> > So regression seems to be between v4.9 and v4.10. Any ideas?
> 
> Interesting... seems there are no sound relevant changes after v4.9.
> 
> Looks like there are only three commits after v4.9 for sound/soc which 
> are built for Nokia N900:
> 
> e411b0b5eb9b65257a050eac333d181d6e00e2c6
> e7aa450fe17890e59db7d3c2d8eff5b6b41fc531
> 63c3194b82530bd71fd49db84eb7ab656b8d404a
> 
> Maybe something not related to sound/soc could broke it?

Lets see.

a9042defa29a01cc538b742eab047848e9b5ae14 -- works ok.
ce38207f161513ee3d2bd3860489f07ebe65bc78 --

alsactl: set_control:1328: failed to obtain info for control #229 (No
such file or directory)

and broken in-call speaker. So this merge breaks stuff:

commit ce38207f161513ee3d2bd3860489f07ebe65bc78
Merge: a9042de 995c6a7
Author: Linus Torvalds <torvalds@linux-foundation.org>
Date:   Wed Dec 14 11:14:28 2016 -0800

    Merge tag 'sound-4.10-rc1' of
    git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
...
      Below are some highlights:

      ASoC:
             - support for stereo DAPM controls
	            - some initial work on the of-graph sound card
		           - regmap conversions of the remaining AC'97
      drivers
             - a new version of the topology ABI; this should be
      backward
               compatible
	              - updates / cleanups of rsnd, sunxi, sti,
      nau8825, samsung, arizona,
               Intel skylake, atom-sst
	              - new drivers for Cirrus Logic CS42L42, Qualcomm
      MSM8916-WCD, and
               Realtek RT5665
...

Best regards,
									Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20170115/2c305712/attachment.sig>

^ permalink raw reply

* [PATCH net-next v3 04/10] net: dsa: Move ports assignment closer to error checking
From: Sergei Shtylyov @ 2017-01-15 10:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170114214713.28109-5-f.fainelli@gmail.com>

Hello!

On 1/15/2017 12:47 AM, Florian Fainelli wrote:

> Move the assignment of ports in _dsa_register_switch() closer to where
> it is checked, no functional change. Re-order declarations to be

    "Be" not needed.

> preserve the inverted christmas tree style.
>
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
[...]

MBR, Sergei

^ permalink raw reply

* [PATCH net-next v3 05/10] drivers: base: Add device_find_class()
From: Greg KH @ 2017-01-15 11:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170114214713.28109-6-f.fainelli@gmail.com>

On Sat, Jan 14, 2017 at 01:47:08PM -0800, Florian Fainelli wrote:
> Add a helper function to lookup a device reference given a class name.
> This is a preliminary patch to remove adhoc code from net/dsa/dsa.c and
> make it more generic.
> 
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
> ---
>  drivers/base/core.c    | 19 +++++++++++++++++++
>  include/linux/device.h |  1 +
>  2 files changed, 20 insertions(+)
> 
> diff --git a/drivers/base/core.c b/drivers/base/core.c
> index 020ea7f05520..3dd6047c10d8 100644
> --- a/drivers/base/core.c
> +++ b/drivers/base/core.c
> @@ -2065,6 +2065,25 @@ struct device *device_find_child(struct device *parent, void *data,
>  }
>  EXPORT_SYMBOL_GPL(device_find_child);
>  
> +static int dev_is_class(struct device *dev, void *class)
> +{
> +	if (dev->class != NULL && !strcmp(dev->class->name, class))
> +		return 1;
> +
> +	return 0;
> +}
> +
> +struct device *device_find_class(struct device *parent, char *class)

Why are you using the char * for a class, and not just a pointer to
"struct class"?  That seems to be the most logical one, no need to rely
on string comparisons here.

Also, what is this being used for?  You aren't trying to walk up the
device heirachy to find a specific "type" of device, are you?  If so,
ugh, I ranted about this in the past when the hyperv driver was trying
to do such a thing...

> +{
> +	if (dev_is_class(parent, class)) {
> +		get_device(parent);
> +		return parent;
> +	}
> +
> +	return device_find_child(parent, class, dev_is_class);

You are trying to find a peer device with the same parent that belongs
to a specific class?

Again, what is this being used for?

And all exported driver core functions should have full kerneldoc
information for them so that people know how to use them, and what the
constraints are (see device_find_child() as an example.)  Please do that
here as well because you are returning a pointer to a structure with the
reference count incremented, callers need to know that.

thanks,

greg k-h

^ permalink raw reply

* [PATCH net-next v3 06/10] net: dsa: Migrate to device_find_class()
From: Greg KH @ 2017-01-15 11:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170114214713.28109-7-f.fainelli@gmail.com>

On Sat, Jan 14, 2017 at 01:47:09PM -0800, Florian Fainelli wrote:
> Now that the base device driver code provides an identical
> implementation of dev_find_class() utilize device_find_class() instead
> of our own version of it.
> 
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
> ---
>  net/dsa/dsa.c | 22 ++--------------------
>  1 file changed, 2 insertions(+), 20 deletions(-)
> 
> diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
> index 2306d1b87c83..77fa4c4f5828 100644
> --- a/net/dsa/dsa.c
> +++ b/net/dsa/dsa.c
> @@ -455,29 +455,11 @@ EXPORT_SYMBOL_GPL(dsa_switch_resume);
>  #endif
>  
>  /* platform driver init and cleanup *****************************************/
> -static int dev_is_class(struct device *dev, void *class)
> -{
> -	if (dev->class != NULL && !strcmp(dev->class->name, class))
> -		return 1;
> -
> -	return 0;
> -}
> -
> -static struct device *dev_find_class(struct device *parent, char *class)
> -{
> -	if (dev_is_class(parent, class)) {
> -		get_device(parent);
> -		return parent;
> -	}
> -
> -	return device_find_child(parent, class, dev_is_class);
> -}
> -
>  struct mii_bus *dsa_host_dev_to_mii_bus(struct device *dev)
>  {
>  	struct device *d;
>  
> -	d = dev_find_class(dev, "mdio_bus");
> +	d = device_find_class(dev, "mdio_bus");
>  	if (d != NULL) {
>  		struct mii_bus *bus;

You want a peer of your device on a specific class?  What is this for?

> @@ -495,7 +477,7 @@ static struct net_device *dev_to_net_device(struct device *dev)
>  {
>  	struct device *d;
>  
> -	d = dev_find_class(dev, "net");
> +	d = device_find_class(dev, "net");
>  	if (d != NULL) {
>  		struct net_device *nd;

Again, huh?  What is the device heirachy here that is so odd that this
type of function is needed?

totally confused,

greg k-h

^ permalink raw reply

* [PATCH net-next v3 07/10] net: Relocate dev_to_net_device() into core
From: Greg KH @ 2017-01-15 11:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170114214713.28109-8-f.fainelli@gmail.com>

On Sat, Jan 14, 2017 at 01:47:10PM -0800, Florian Fainelli wrote:
> dev_to_net_device() is moved from net/dsa/dsa.c to net/core/dev.c since
> it going to be used by net/dsa/dsa2.c and the namespace of the function
> justifies making it available to other users potentially.
> 
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
> ---
>  include/linux/netdevice.h |  2 ++
>  net/core/dev.c            | 19 +++++++++++++++++++
>  net/dsa/dsa.c             | 18 ------------------
>  3 files changed, 21 insertions(+), 18 deletions(-)
> 
> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> index 97ae0ac513ee..6d021c37b774 100644
> --- a/include/linux/netdevice.h
> +++ b/include/linux/netdevice.h
> @@ -4390,4 +4390,6 @@ do {								\
>  #define PTYPE_HASH_SIZE	(16)
>  #define PTYPE_HASH_MASK	(PTYPE_HASH_SIZE - 1)
>  
> +struct net_device *dev_to_net_device(struct device *dev);
> +
>  #endif	/* _LINUX_NETDEVICE_H */
> diff --git a/net/core/dev.c b/net/core/dev.c
> index ad5959e56116..7547e2ccc06b 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -8128,6 +8128,25 @@ const char *netdev_drivername(const struct net_device *dev)
>  	return empty;
>  }
>  
> +struct net_device *dev_to_net_device(struct device *dev)
> +{
> +	struct device *d;
> +
> +	d = device_find_class(dev, "net");
> +	if (d) {
> +		struct net_device *nd;
> +
> +		nd = to_net_dev(d);
> +		dev_hold(nd);
> +		put_device(d);
> +
> +		return nd;
> +	}
> +
> +	return NULL;
> +}
> +EXPORT_SYMBOL_GPL(dev_to_net_device);

This really isn't just a "struct device to net device cast" type
function, (otherwise a simple container_of() would work).  You are
walking the device tree and assuming it is in a specific order so that
this function works.  You better document the hell out of this,
otherwise people are going to try to use this and get very confused,
very quickly...

thanks,

greg k-h

^ permalink raw reply

* [PATCH net-next v3 00/10] net: dsa: Support for pdata in dsa2
From: Greg KH @ 2017-01-15 11:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170114214713.28109-1-f.fainelli@gmail.com>

On Sat, Jan 14, 2017 at 01:47:03PM -0800, Florian Fainelli wrote:
> Hi all,
> 
> This is not exactly new, and was sent before, although back then, I did not
> have an user of the pre-declared MDIO board information, but now we do. Note
> that I have additional changes queued up to have b53 register platform data for
> MIPS bcm47xx and bcm63xx.
> 
> Yes I know that we should have the Orion platforms eventually be converted to
> Device Tree, but until that happens, I don't want any remaining users of the
> old "dsa" platform device (hence the previous DTS submissions for ARM/mvebu)
> and, there will be platforms out there that most likely won't never see DT
> coming their way (BCM47xx is almost 100% sure, BCM63xx maybe not in a distant
> future).
> 
> We would probably want the whole series to be merged via David Miller's tree
> to simplify things.
> 
> Greg, can you Ack/Nack patch 5 since it touched the core LDD?

I've NAKed them for now, you need to describe what you are trying to do
here, as it doesn't make any sense to me at the moment.

thanks,

greg k-h

^ permalink raw reply

* [PATCH RFC 2/2] ARM: nommu: remap exception base address to RAM
From: Afzal Mohammed @ 2017-01-15 11:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170107171339.GA5044@afzalpc>

Hi,

On Sat, Jan 07, 2017 at 10:43:39PM +0530, Afzal Mohammed wrote:
> On Tue, Dec 13, 2016 at 10:02:26AM +0000, Russell King - ARM Linux wrote:

> > Also, if the region setup for the vectors was moved as well, it would
> > then be possible to check the ID registers to determine whether this
> > is supported, and make the decision where to locate the vectors base
> > more dynamically.
> 
> This would affect Cortex-R's, which is a bit concerning due to lack of
> those platforms with me, let me try to get it right.

QEMU too doesn't seem to provide a Cortex-R target

> Seems translating __setup_mpu() altogether to C

afaics, a kind of C translation is already present as
mpu_setup_region() in arch/arm/mm/nommu.c that takes care of
MPU_RAM_REGION only. And that seems to be a kind of redundant as it is
also done in asm at __setup_mpu(). Git blames asm & C to consecutive
commits, that makes me a little shaky about the conclusion on it being
redundant.

> & installing at a later, but suitable place might be better.

But looks like enabling MPU can't be moved to C & that would
necessitate keeping at least some portion of__setu_mpu() in asm.

Instead, moving region setup only for vectors to C as Russell
suggested at first would have to be done.

A kind of diff at the end is in my mind, with additional changes to
handle the similar during secondary cpu bringup too.

Thinking of invoking mpu_setup() from secondary_start_kernel() in
arch/arm/kernel/smp.c, with mpu_setup() being slightly modified to
avoid storing region details again when invoked by secondary cpu's.

Vladimir, once changes are done after a revisit, i would need your
help to test on Cortex-R.

As an aside, wasn't aware of the fact that Cortex-R supports SMP
Linux, had thought that, of !MMU one's, only Blackfin & J2 had it.


> Also !MMU Kernel could boot on 3 ARM v7-A platforms - AM335x Beagle
> Bone (A8), AM437x IDK (A9) & Vybrid VF610 (on A5 core, note that it
> has M4 core too)

Talking about Cortex-M, AMx3's too have it, to be specific M3, but
they are not Linux-able unlike the one in VF610.

Regards
afzal

--->8---

diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S
index e0565d73e49e..f8ac79b6136d 100644
--- a/arch/arm/kernel/head-nommu.S
+++ b/arch/arm/kernel/head-nommu.S
@@ -249,20 +249,6 @@ ENTRY(__setup_mpu)
 	setup_region r0, r5, r6, MPU_INSTR_SIDE @ 0x0, BG region, enabled
 2:	isb
 
-	/* Vectors region */
-	set_region_nr r0, #MPU_VECTORS_REGION
-	isb
-	/* Shared, inaccessible to PL0, rw PL1 */
-	mov	r0, #CONFIG_VECTORS_BASE	@ Cover from VECTORS_BASE
-	ldr	r5,=(MPU_AP_PL1RW_PL0NA | MPU_RGN_NORMAL)
-	/* Writing N to bits 5:1 (RSR_SZ) --> region size 2^N+1 */
-	mov	r6, #(((2 * PAGE_SHIFT - 1) << MPU_RSR_SZ) | 1 << MPU_RSR_EN)
-
-	setup_region r0, r5, r6, MPU_DATA_SIDE	@ VECTORS_BASE, PL0 NA, enabled
-	beq	3f				@ Memory-map not unified
-	setup_region r0, r5, r6, MPU_INSTR_SIDE	@ VECTORS_BASE, PL0 NA, enabled
-3:	isb
-
 	/* Enable the MPU */
 	mrc	p15, 0, r0, c1, c0, 0		@ Read SCTLR
 	bic     r0, r0, #CR_BR			@ Disable the 'default mem-map'
diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c
index e82056df0635..7fe8906322d5 100644
--- a/arch/arm/mm/nommu.c
+++ b/arch/arm/mm/nommu.c
@@ -269,12 +269,19 @@ void __init mpu_setup(void)
 					ilog2(memblock.memory.regions[0].size),
 					MPU_AP_PL1RW_PL0RW | MPU_RGN_NORMAL);
 	if (region_err) {
-		panic("MPU region initialization failure! %d", region_err);
+		panic("MPU RAM region initialization failure! %d", region_err);
 	} else {
-		pr_info("Using ARMv7 PMSA Compliant MPU. "
-			 "Region independence: %s, Max regions: %d\n",
-			mpu_iside_independent() ? "Yes" : "No",
-			mpu_max_regions());
+		region_err = mpu_setup_region(MPU_VECTORS_REGION, vectors_base,
+					ilog2(memblock.memory.regions[0].size),
+					MPU_AP_PL1RW_PL0NA | MPU_RGN_NORMAL);
+		if (region_err) {
+			panic("MPU VECTOR region initialization failure! %d",
+			      region_err);
+		} else {
+			pr_info("Using ARMv7 PMSA Compliant MPU. "
+				"Region independence: %s, Max regions: %d\n",
+				mpu_iside_independent() ? "Yes" : "No",
+				mpu_max_regions());
 	}
 }
 #else

^ permalink raw reply related

* [PATCH v9 3/3] iio: adc: add support for Allwinner SoCs ADC
From: Lars-Peter Clausen @ 2017-01-15 12:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161213143332.24988-4-quentin.schulz@free-electrons.com>

On 12/13/2016 03:33 PM, Quentin Schulz wrote:

> +	indio_dev->name = dev_name(&pdev->dev);

The name is supposed to be the type of the device, e.g. part name, not the
name of parent device instance. This could e.g. come from a name field in
the gpadc_data struct.

^ permalink raw reply

* [PATCH 3/4] iio: adc: add a driver for the SAR ADC found in Amlogic Meson SoCs
From: Lars-Peter Clausen @ 2017-01-15 12:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170111174334.24343-4-martin.blumenstingl@googlemail.com>

On 01/11/2017 06:43 PM, Martin Blumenstingl wrote:
> +	indio_dev->name = dev_name(&pdev->dev);

The name is supposed to be the type of the device, e.g. part name, not the
name of parent device instance. E.g. meson-gxbb-saradc or meson-gxl-saradc
in this case.

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox