Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] arm: spin one more cycle in timer-based delays
From: Mason @ 2016-11-15 13:36 UTC (permalink / raw)
  To: linux-arm-kernel

When polling a tick counter in a busy loop, one might sample the
counter just *before* it is updated, and then again just *after*
it is updated. In that case, while mathematically v2-v1 equals 1,
only epsilon has really passed.

So, if a caller requests an N-cycle delay, we spin until v2-v1
is strictly greater than N to avoid these random corner cases.

Signed-off-by: Mason <slash.tmp@free.fr>
---
 arch/arm/lib/delay.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/lib/delay.c b/arch/arm/lib/delay.c
index 69aad80a3af4..3f1cd15ca102 100644
--- a/arch/arm/lib/delay.c
+++ b/arch/arm/lib/delay.c
@@ -60,7 +60,7 @@ static void __timer_delay(unsigned long cycles)
 {
 	cycles_t start = get_cycles();
 
-	while ((get_cycles() - start) < cycles)
+	while ((get_cycles() - start) <= cycles)
 		cpu_relax();
 }
 
-- 
2.9.0

^ permalink raw reply related

* [PATCH v3 1/2] phy: rockchip-inno-usb2: support otg-port for rk3399
From: Kishon Vijay Abraham I @ 2016-11-15 13:39 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1478520529-8869-2-git-send-email-wulf@rock-chips.com>



On Monday 07 November 2016 05:38 PM, William Wu wrote:
> The rk3399 SoC USB2 PHY is comprised of one Host port and
> one OTG port. And OTG port is for USB2.0 part of USB3.0 OTG
> controller, as a part to construct a fully feature Type-C
> subsystem.
> 
> With this patch, we can support OTG port with the following
> functions:
> - Support BC1.2 charger detect, and use extcon notifier to
>   send USB charger types to power driver.
> - Support PHY suspend for power management.
> - Support OTG Host only mode.
> 
> Signed-off-by: William Wu <wulf@rock-chips.com>

merged.

Thanks
Kishon
> ---
> Changes in v3:
> - split the clock fix into a separate patch 
> 
> Changes in v2:
> - remove wakelock
> 
>  drivers/phy/phy-rockchip-inno-usb2.c | 591 +++++++++++++++++++++++++++++++++--
>  1 file changed, 561 insertions(+), 30 deletions(-)
> 
> diff --git a/drivers/phy/phy-rockchip-inno-usb2.c b/drivers/phy/phy-rockchip-inno-usb2.c
> index ac20310..ecfd7d1 100644
> --- a/drivers/phy/phy-rockchip-inno-usb2.c
> +++ b/drivers/phy/phy-rockchip-inno-usb2.c
> @@ -17,6 +17,7 @@
>  #include <linux/clk.h>
>  #include <linux/clk-provider.h>
>  #include <linux/delay.h>
> +#include <linux/extcon.h>
>  #include <linux/interrupt.h>
>  #include <linux/io.h>
>  #include <linux/gpio/consumer.h>
> @@ -30,11 +31,15 @@
>  #include <linux/of_platform.h>
>  #include <linux/phy/phy.h>
>  #include <linux/platform_device.h>
> +#include <linux/power_supply.h>
>  #include <linux/regmap.h>
>  #include <linux/mfd/syscon.h>
> +#include <linux/usb/of.h>
> +#include <linux/usb/otg.h>
>  
>  #define BIT_WRITEABLE_SHIFT	16
> -#define SCHEDULE_DELAY	(60 * HZ)
> +#define SCHEDULE_DELAY		(60 * HZ)
> +#define OTG_SCHEDULE_DELAY	(2 * HZ)
>  
>  enum rockchip_usb2phy_port_id {
>  	USB2PHY_PORT_OTG,
> @@ -49,6 +54,37 @@ enum rockchip_usb2phy_host_state {
>  	PHY_STATE_FS_LS_ONLINE	= 4,
>  };
>  
> +/**
> + * Different states involved in USB charger detection.
> + * USB_CHG_STATE_UNDEFINED	USB charger is not connected or detection
> + *				process is not yet started.
> + * USB_CHG_STATE_WAIT_FOR_DCD	Waiting for Data pins contact.
> + * USB_CHG_STATE_DCD_DONE	Data pin contact is detected.
> + * USB_CHG_STATE_PRIMARY_DONE	Primary detection is completed (Detects
> + *				between SDP and DCP/CDP).
> + * USB_CHG_STATE_SECONDARY_DONE	Secondary detection is completed (Detects
> + *				between DCP and CDP).
> + * USB_CHG_STATE_DETECTED	USB charger type is determined.
> + */
> +enum usb_chg_state {
> +	USB_CHG_STATE_UNDEFINED = 0,
> +	USB_CHG_STATE_WAIT_FOR_DCD,
> +	USB_CHG_STATE_DCD_DONE,
> +	USB_CHG_STATE_PRIMARY_DONE,
> +	USB_CHG_STATE_SECONDARY_DONE,
> +	USB_CHG_STATE_DETECTED,
> +};
> +
> +static const unsigned int rockchip_usb2phy_extcon_cable[] = {
> +	EXTCON_USB,
> +	EXTCON_USB_HOST,
> +	EXTCON_CHG_USB_SDP,
> +	EXTCON_CHG_USB_CDP,
> +	EXTCON_CHG_USB_DCP,
> +	EXTCON_CHG_USB_SLOW,
> +	EXTCON_NONE,
> +};
> +
>  struct usb2phy_reg {
>  	unsigned int	offset;
>  	unsigned int	bitend;
> @@ -58,19 +94,55 @@ struct usb2phy_reg {
>  };
>  
>  /**
> + * struct rockchip_chg_det_reg: usb charger detect registers
> + * @cp_det: charging port detected successfully.
> + * @dcp_det: dedicated charging port detected successfully.
> + * @dp_det: assert data pin connect successfully.
> + * @idm_sink_en: open dm sink curren.
> + * @idp_sink_en: open dp sink current.
> + * @idp_src_en: open dm source current.
> + * @rdm_pdwn_en: open dm pull down resistor.
> + * @vdm_src_en: open dm voltage source.
> + * @vdp_src_en: open dp voltage source.
> + * @opmode: utmi operational mode.
> + */
> +struct rockchip_chg_det_reg {
> +	struct usb2phy_reg	cp_det;
> +	struct usb2phy_reg	dcp_det;
> +	struct usb2phy_reg	dp_det;
> +	struct usb2phy_reg	idm_sink_en;
> +	struct usb2phy_reg	idp_sink_en;
> +	struct usb2phy_reg	idp_src_en;
> +	struct usb2phy_reg	rdm_pdwn_en;
> +	struct usb2phy_reg	vdm_src_en;
> +	struct usb2phy_reg	vdp_src_en;
> +	struct usb2phy_reg	opmode;
> +};
> +
> +/**
>   * struct rockchip_usb2phy_port_cfg: usb-phy port configuration.
>   * @phy_sus: phy suspend register.
> + * @bvalid_det_en: vbus valid rise detection enable register.
> + * @bvalid_det_st: vbus valid rise detection status register.
> + * @bvalid_det_clr: vbus valid rise detection clear register.
>   * @ls_det_en: linestate detection enable register.
>   * @ls_det_st: linestate detection state register.
>   * @ls_det_clr: linestate detection clear register.
> + * @utmi_avalid: utmi vbus avalid status register.
> + * @utmi_bvalid: utmi vbus bvalid status register.
>   * @utmi_ls: utmi linestate state register.
>   * @utmi_hstdet: utmi host disconnect register.
>   */
>  struct rockchip_usb2phy_port_cfg {
>  	struct usb2phy_reg	phy_sus;
> +	struct usb2phy_reg	bvalid_det_en;
> +	struct usb2phy_reg	bvalid_det_st;
> +	struct usb2phy_reg	bvalid_det_clr;
>  	struct usb2phy_reg	ls_det_en;
>  	struct usb2phy_reg	ls_det_st;
>  	struct usb2phy_reg	ls_det_clr;
> +	struct usb2phy_reg	utmi_avalid;
> +	struct usb2phy_reg	utmi_bvalid;
>  	struct usb2phy_reg	utmi_ls;
>  	struct usb2phy_reg	utmi_hstdet;
>  };
> @@ -80,31 +152,51 @@ struct rockchip_usb2phy_port_cfg {
>   * @reg: the address offset of grf for usb-phy config.
>   * @num_ports: specify how many ports that the phy has.
>   * @clkout_ctl: keep on/turn off output clk of phy.
> + * @chg_det: charger detection registers.
>   */
>  struct rockchip_usb2phy_cfg {
>  	unsigned int	reg;
>  	unsigned int	num_ports;
>  	struct usb2phy_reg	clkout_ctl;
>  	const struct rockchip_usb2phy_port_cfg	port_cfgs[USB2PHY_NUM_PORTS];
> +	const struct rockchip_chg_det_reg	chg_det;
>  };
>  
>  /**
>   * struct rockchip_usb2phy_port: usb-phy port data.
>   * @port_id: flag for otg port or host port.
>   * @suspended: phy suspended flag.
> + * @utmi_avalid: utmi avalid status usage flag.
> + *	true	- use avalid to get vbus status
> + *	flase	- use bvalid to get vbus status
> + * @vbus_attached: otg device vbus status.
> + * @bvalid_irq: IRQ number assigned for vbus valid rise detection.
>   * @ls_irq: IRQ number assigned for linestate detection.
>   * @mutex: for register updating in sm_work.
> - * @sm_work: OTG state machine work.
> + * @chg_work: charge detect work.
> + * @otg_sm_work: OTG state machine work.
> + * @sm_work: HOST state machine work.
>   * @phy_cfg: port register configuration, assigned by driver data.
> + * @event_nb: hold event notification callback.
> + * @state: define OTG enumeration states before device reset.
> + * @mode: the dr_mode of the controller.
>   */
>  struct rockchip_usb2phy_port {
>  	struct phy	*phy;
>  	unsigned int	port_id;
>  	bool		suspended;
> +	bool		utmi_avalid;
> +	bool		vbus_attached;
> +	int		bvalid_irq;
>  	int		ls_irq;
>  	struct mutex	mutex;
> +	struct		delayed_work chg_work;
> +	struct		delayed_work otg_sm_work;
>  	struct		delayed_work sm_work;
>  	const struct	rockchip_usb2phy_port_cfg *port_cfg;
> +	struct notifier_block	event_nb;
> +	enum usb_otg_state	state;
> +	enum usb_dr_mode	mode;
>  };
>  
>  /**
> @@ -113,6 +205,11 @@ struct rockchip_usb2phy_port {
>   * @clk: clock struct of phy input clk.
>   * @clk480m: clock struct of phy output clk.
>   * @clk_hw: clock struct of phy output clk management.
> + * @chg_state: states involved in USB charger detection.
> + * @chg_type: USB charger types.
> + * @dcd_retries: The retry count used to track Data contact
> + *		 detection process.
> + * @edev: extcon device for notification registration
>   * @phy_cfg: phy register configuration, assigned by driver data.
>   * @ports: phy port instance.
>   */
> @@ -122,6 +219,10 @@ struct rockchip_usb2phy {
>  	struct clk	*clk;
>  	struct clk	*clk480m;
>  	struct clk_hw	clk480m_hw;
> +	enum usb_chg_state	chg_state;
> +	enum power_supply_type	chg_type;
> +	u8			dcd_retries;
> +	struct extcon_dev	*edev;
>  	const struct rockchip_usb2phy_cfg	*phy_cfg;
>  	struct rockchip_usb2phy_port	ports[USB2PHY_NUM_PORTS];
>  };
> @@ -263,33 +364,84 @@ rockchip_usb2phy_clk480m_register(struct rockchip_usb2phy *rphy)
>  	return ret;
>  }
>  
> -static int rockchip_usb2phy_init(struct phy *phy)
> +static int rockchip_usb2phy_extcon_register(struct rockchip_usb2phy *rphy)
>  {
> -	struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
> -	struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent);
>  	int ret;
> +	struct device_node *node = rphy->dev->of_node;
> +	struct extcon_dev *edev;
> +
> +	if (of_property_read_bool(node, "extcon")) {
> +		edev = extcon_get_edev_by_phandle(rphy->dev, 0);
> +		if (IS_ERR(edev)) {
> +			if (PTR_ERR(edev) != -EPROBE_DEFER)
> +				dev_err(rphy->dev, "Invalid or missing extcon\n");
> +			return PTR_ERR(edev);
> +		}
> +	} else {
> +		/* Initialize extcon device */
> +		edev = devm_extcon_dev_allocate(rphy->dev,
> +						rockchip_usb2phy_extcon_cable);
>  
> -	if (rport->port_id == USB2PHY_PORT_HOST) {
> -		/* clear linestate and enable linestate detect irq */
> -		mutex_lock(&rport->mutex);
> +		if (IS_ERR(edev))
> +			return -ENOMEM;
>  
> -		ret = property_enable(rphy, &rport->port_cfg->ls_det_clr, true);
> +		ret = devm_extcon_dev_register(rphy->dev, edev);
>  		if (ret) {
> -			mutex_unlock(&rport->mutex);
> +			dev_err(rphy->dev, "failed to register extcon device\n");
>  			return ret;
>  		}
> +	}
>  
> -		ret = property_enable(rphy, &rport->port_cfg->ls_det_en, true);
> -		if (ret) {
> -			mutex_unlock(&rport->mutex);
> -			return ret;
> +	rphy->edev = edev;
> +
> +	return 0;
> +}
> +
> +static int rockchip_usb2phy_init(struct phy *phy)
> +{
> +	struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
> +	struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent);
> +	int ret = 0;
> +
> +	mutex_lock(&rport->mutex);
> +
> +	if (rport->port_id == USB2PHY_PORT_OTG) {
> +		if (rport->mode != USB_DR_MODE_HOST) {
> +			/* clear bvalid status and enable bvalid detect irq */
> +			ret = property_enable(rphy,
> +					      &rport->port_cfg->bvalid_det_clr,
> +					      true);
> +			if (ret)
> +				goto out;
> +
> +			ret = property_enable(rphy,
> +					      &rport->port_cfg->bvalid_det_en,
> +					      true);
> +			if (ret)
> +				goto out;
> +
> +			schedule_delayed_work(&rport->otg_sm_work,
> +					      OTG_SCHEDULE_DELAY);
> +		} else {
> +			/* If OTG works in host only mode, do nothing. */
> +			dev_dbg(&rport->phy->dev, "mode %d\n", rport->mode);
>  		}
> +	} else if (rport->port_id == USB2PHY_PORT_HOST) {
> +		/* clear linestate and enable linestate detect irq */
> +		ret = property_enable(rphy, &rport->port_cfg->ls_det_clr, true);
> +		if (ret)
> +			goto out;
> +
> +		ret = property_enable(rphy, &rport->port_cfg->ls_det_en, true);
> +		if (ret)
> +			goto out;
>  
> -		mutex_unlock(&rport->mutex);
>  		schedule_delayed_work(&rport->sm_work, SCHEDULE_DELAY);
>  	}
>  
> -	return 0;
> +out:
> +	mutex_unlock(&rport->mutex);
> +	return ret;
>  }
>  
>  static int rockchip_usb2phy_power_on(struct phy *phy)
> @@ -340,7 +492,11 @@ static int rockchip_usb2phy_exit(struct phy *phy)
>  {
>  	struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
>  
> -	if (rport->port_id == USB2PHY_PORT_HOST)
> +	if (rport->port_id == USB2PHY_PORT_OTG &&
> +	    rport->mode != USB_DR_MODE_HOST) {
> +		cancel_delayed_work_sync(&rport->otg_sm_work);
> +		cancel_delayed_work_sync(&rport->chg_work);
> +	} else if (rport->port_id == USB2PHY_PORT_HOST)
>  		cancel_delayed_work_sync(&rport->sm_work);
>  
>  	return 0;
> @@ -354,6 +510,249 @@ static const struct phy_ops rockchip_usb2phy_ops = {
>  	.owner		= THIS_MODULE,
>  };
>  
> +static void rockchip_usb2phy_otg_sm_work(struct work_struct *work)
> +{
> +	struct rockchip_usb2phy_port *rport =
> +		container_of(work, struct rockchip_usb2phy_port,
> +			     otg_sm_work.work);
> +	struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
> +	static unsigned int cable;
> +	unsigned long delay;
> +	bool vbus_attach, sch_work, notify_charger;
> +
> +	if (rport->utmi_avalid)
> +		vbus_attach =
> +			property_enabled(rphy, &rport->port_cfg->utmi_avalid);
> +	else
> +		vbus_attach =
> +			property_enabled(rphy, &rport->port_cfg->utmi_bvalid);
> +
> +	sch_work = false;
> +	notify_charger = false;
> +	delay = OTG_SCHEDULE_DELAY;
> +	dev_dbg(&rport->phy->dev, "%s otg sm work\n",
> +		usb_otg_state_string(rport->state));
> +
> +	switch (rport->state) {
> +	case OTG_STATE_UNDEFINED:
> +		rport->state = OTG_STATE_B_IDLE;
> +		if (!vbus_attach)
> +			rockchip_usb2phy_power_off(rport->phy);
> +		/* fall through */
> +	case OTG_STATE_B_IDLE:
> +		if (extcon_get_cable_state_(rphy->edev, EXTCON_USB_HOST) > 0) {
> +			dev_dbg(&rport->phy->dev, "usb otg host connect\n");
> +			rport->state = OTG_STATE_A_HOST;
> +			rockchip_usb2phy_power_on(rport->phy);
> +			return;
> +		} else if (vbus_attach) {
> +			dev_dbg(&rport->phy->dev, "vbus_attach\n");
> +			switch (rphy->chg_state) {
> +			case USB_CHG_STATE_UNDEFINED:
> +				schedule_delayed_work(&rport->chg_work, 0);
> +				return;
> +			case USB_CHG_STATE_DETECTED:
> +				switch (rphy->chg_type) {
> +				case POWER_SUPPLY_TYPE_USB:
> +					dev_dbg(&rport->phy->dev,
> +						"sdp cable is connecetd\n");
> +					rockchip_usb2phy_power_on(rport->phy);
> +					rport->state = OTG_STATE_B_PERIPHERAL;
> +					notify_charger = true;
> +					sch_work = true;
> +					cable = EXTCON_CHG_USB_SDP;
> +					break;
> +				case POWER_SUPPLY_TYPE_USB_DCP:
> +					dev_dbg(&rport->phy->dev,
> +						"dcp cable is connecetd\n");
> +					rockchip_usb2phy_power_off(rport->phy);
> +					notify_charger = true;
> +					sch_work = true;
> +					cable = EXTCON_CHG_USB_DCP;
> +					break;
> +				case POWER_SUPPLY_TYPE_USB_CDP:
> +					dev_dbg(&rport->phy->dev,
> +						"cdp cable is connecetd\n");
> +					rockchip_usb2phy_power_on(rport->phy);
> +					rport->state = OTG_STATE_B_PERIPHERAL;
> +					notify_charger = true;
> +					sch_work = true;
> +					cable = EXTCON_CHG_USB_CDP;
> +					break;
> +				default:
> +					break;
> +				}
> +				break;
> +			default:
> +				break;
> +			}
> +		} else {
> +			notify_charger = true;
> +			rphy->chg_state = USB_CHG_STATE_UNDEFINED;
> +			rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN;
> +		}
> +
> +		if (rport->vbus_attached != vbus_attach) {
> +			rport->vbus_attached = vbus_attach;
> +
> +			if (notify_charger && rphy->edev)
> +				extcon_set_cable_state_(rphy->edev,
> +							cable, vbus_attach);
> +		}
> +		break;
> +	case OTG_STATE_B_PERIPHERAL:
> +		if (!vbus_attach) {
> +			dev_dbg(&rport->phy->dev, "usb disconnect\n");
> +			rphy->chg_state = USB_CHG_STATE_UNDEFINED;
> +			rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN;
> +			rport->state = OTG_STATE_B_IDLE;
> +			delay = 0;
> +			rockchip_usb2phy_power_off(rport->phy);
> +		}
> +		sch_work = true;
> +		break;
> +	case OTG_STATE_A_HOST:
> +		if (extcon_get_cable_state_(rphy->edev, EXTCON_USB_HOST) == 0) {
> +			dev_dbg(&rport->phy->dev, "usb otg host disconnect\n");
> +			rport->state = OTG_STATE_B_IDLE;
> +			rockchip_usb2phy_power_off(rport->phy);
> +		}
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	if (sch_work)
> +		schedule_delayed_work(&rport->otg_sm_work, delay);
> +}
> +
> +static const char *chg_to_string(enum power_supply_type chg_type)
> +{
> +	switch (chg_type) {
> +	case POWER_SUPPLY_TYPE_USB:
> +		return "USB_SDP_CHARGER";
> +	case POWER_SUPPLY_TYPE_USB_DCP:
> +		return "USB_DCP_CHARGER";
> +	case POWER_SUPPLY_TYPE_USB_CDP:
> +		return "USB_CDP_CHARGER";
> +	default:
> +		return "INVALID_CHARGER";
> +	}
> +}
> +
> +static void rockchip_chg_enable_dcd(struct rockchip_usb2phy *rphy,
> +				    bool en)
> +{
> +	property_enable(rphy, &rphy->phy_cfg->chg_det.rdm_pdwn_en, en);
> +	property_enable(rphy, &rphy->phy_cfg->chg_det.idp_src_en, en);
> +}
> +
> +static void rockchip_chg_enable_primary_det(struct rockchip_usb2phy *rphy,
> +					    bool en)
> +{
> +	property_enable(rphy, &rphy->phy_cfg->chg_det.vdp_src_en, en);
> +	property_enable(rphy, &rphy->phy_cfg->chg_det.idm_sink_en, en);
> +}
> +
> +static void rockchip_chg_enable_secondary_det(struct rockchip_usb2phy *rphy,
> +					      bool en)
> +{
> +	property_enable(rphy, &rphy->phy_cfg->chg_det.vdm_src_en, en);
> +	property_enable(rphy, &rphy->phy_cfg->chg_det.idp_sink_en, en);
> +}
> +
> +#define CHG_DCD_POLL_TIME	(100 * HZ / 1000)
> +#define CHG_DCD_MAX_RETRIES	6
> +#define CHG_PRIMARY_DET_TIME	(40 * HZ / 1000)
> +#define CHG_SECONDARY_DET_TIME	(40 * HZ / 1000)
> +static void rockchip_chg_detect_work(struct work_struct *work)
> +{
> +	struct rockchip_usb2phy_port *rport =
> +		container_of(work, struct rockchip_usb2phy_port, chg_work.work);
> +	struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
> +	bool is_dcd, tmout, vout;
> +	unsigned long delay;
> +
> +	dev_dbg(&rport->phy->dev, "chg detection work state = %d\n",
> +		rphy->chg_state);
> +	switch (rphy->chg_state) {
> +	case USB_CHG_STATE_UNDEFINED:
> +		if (!rport->suspended)
> +			rockchip_usb2phy_power_off(rport->phy);
> +		/* put the controller in non-driving mode */
> +		property_enable(rphy, &rphy->phy_cfg->chg_det.opmode, false);
> +		/* Start DCD processing stage 1 */
> +		rockchip_chg_enable_dcd(rphy, true);
> +		rphy->chg_state = USB_CHG_STATE_WAIT_FOR_DCD;
> +		rphy->dcd_retries = 0;
> +		delay = CHG_DCD_POLL_TIME;
> +		break;
> +	case USB_CHG_STATE_WAIT_FOR_DCD:
> +		/* get data contact detection status */
> +		is_dcd = property_enabled(rphy, &rphy->phy_cfg->chg_det.dp_det);
> +		tmout = ++rphy->dcd_retries == CHG_DCD_MAX_RETRIES;
> +		/* stage 2 */
> +		if (is_dcd || tmout) {
> +			/* stage 4 */
> +			/* Turn off DCD circuitry */
> +			rockchip_chg_enable_dcd(rphy, false);
> +			/* Voltage Source on DP, Probe on DM */
> +			rockchip_chg_enable_primary_det(rphy, true);
> +			delay = CHG_PRIMARY_DET_TIME;
> +			rphy->chg_state = USB_CHG_STATE_DCD_DONE;
> +		} else {
> +			/* stage 3 */
> +			delay = CHG_DCD_POLL_TIME;
> +		}
> +		break;
> +	case USB_CHG_STATE_DCD_DONE:
> +		vout = property_enabled(rphy, &rphy->phy_cfg->chg_det.cp_det);
> +		rockchip_chg_enable_primary_det(rphy, false);
> +		if (vout) {
> +			/* Voltage Source on DM, Probe on DP  */
> +			rockchip_chg_enable_secondary_det(rphy, true);
> +			delay = CHG_SECONDARY_DET_TIME;
> +			rphy->chg_state = USB_CHG_STATE_PRIMARY_DONE;
> +		} else {
> +			if (tmout) {
> +				/* floating charger found */
> +				rphy->chg_type = POWER_SUPPLY_TYPE_USB_DCP;
> +				rphy->chg_state = USB_CHG_STATE_DETECTED;
> +				delay = 0;
> +			} else {
> +				rphy->chg_type = POWER_SUPPLY_TYPE_USB;
> +				rphy->chg_state = USB_CHG_STATE_DETECTED;
> +				delay = 0;
> +			}
> +		}
> +		break;
> +	case USB_CHG_STATE_PRIMARY_DONE:
> +		vout = property_enabled(rphy, &rphy->phy_cfg->chg_det.dcp_det);
> +		/* Turn off voltage source */
> +		rockchip_chg_enable_secondary_det(rphy, false);
> +		if (vout)
> +			rphy->chg_type = POWER_SUPPLY_TYPE_USB_DCP;
> +		else
> +			rphy->chg_type = POWER_SUPPLY_TYPE_USB_CDP;
> +		/* fall through */
> +	case USB_CHG_STATE_SECONDARY_DONE:
> +		rphy->chg_state = USB_CHG_STATE_DETECTED;
> +		delay = 0;
> +		/* fall through */
> +	case USB_CHG_STATE_DETECTED:
> +		/* put the controller in normal mode */
> +		property_enable(rphy, &rphy->phy_cfg->chg_det.opmode, true);
> +		rockchip_usb2phy_otg_sm_work(&rport->otg_sm_work.work);
> +		dev_info(&rport->phy->dev, "charger = %s\n",
> +			 chg_to_string(rphy->chg_type));
> +		return;
> +	default:
> +		return;
> +	}
> +
> +	schedule_delayed_work(&rport->chg_work, delay);
> +}
> +
>  /*
>   * The function manage host-phy port state and suspend/resume phy port
>   * to save power.
> @@ -485,6 +884,26 @@ static irqreturn_t rockchip_usb2phy_linestate_irq(int irq, void *data)
>  	return IRQ_HANDLED;
>  }
>  
> +static irqreturn_t rockchip_usb2phy_bvalid_irq(int irq, void *data)
> +{
> +	struct rockchip_usb2phy_port *rport = data;
> +	struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
> +
> +	if (!property_enabled(rphy, &rport->port_cfg->bvalid_det_st))
> +		return IRQ_NONE;
> +
> +	mutex_lock(&rport->mutex);
> +
> +	/* clear bvalid detect irq pending status */
> +	property_enable(rphy, &rport->port_cfg->bvalid_det_clr, true);
> +
> +	mutex_unlock(&rport->mutex);
> +
> +	rockchip_usb2phy_otg_sm_work(&rport->otg_sm_work.work);
> +
> +	return IRQ_HANDLED;
> +}
> +
>  static int rockchip_usb2phy_host_port_init(struct rockchip_usb2phy *rphy,
>  					   struct rockchip_usb2phy_port *rport,
>  					   struct device_node *child_np)
> @@ -509,13 +928,86 @@ static int rockchip_usb2phy_host_port_init(struct rockchip_usb2phy *rphy,
>  					IRQF_ONESHOT,
>  					"rockchip_usb2phy", rport);
>  	if (ret) {
> -		dev_err(rphy->dev, "failed to request irq handle\n");
> +		dev_err(rphy->dev, "failed to request linestate irq handle\n");
>  		return ret;
>  	}
>  
>  	return 0;
>  }
>  
> +static int rockchip_otg_event(struct notifier_block *nb,
> +			      unsigned long event, void *ptr)
> +{
> +	struct rockchip_usb2phy_port *rport =
> +		container_of(nb, struct rockchip_usb2phy_port, event_nb);
> +
> +	schedule_delayed_work(&rport->otg_sm_work, OTG_SCHEDULE_DELAY);
> +
> +	return NOTIFY_DONE;
> +}
> +
> +static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy,
> +					  struct rockchip_usb2phy_port *rport,
> +					  struct device_node *child_np)
> +{
> +	int ret;
> +
> +	rport->port_id = USB2PHY_PORT_OTG;
> +	rport->port_cfg = &rphy->phy_cfg->port_cfgs[USB2PHY_PORT_OTG];
> +	rport->state = OTG_STATE_UNDEFINED;
> +
> +	/*
> +	 * set suspended flag to true, but actually don't
> +	 * put phy in suspend mode, it aims to enable usb
> +	 * phy and clock in power_on() called by usb controller
> +	 * driver during probe.
> +	 */
> +	rport->suspended = true;
> +	rport->vbus_attached = false;
> +
> +	mutex_init(&rport->mutex);
> +
> +	rport->mode = of_usb_get_dr_mode_by_phy(child_np, -1);
> +	if (rport->mode == USB_DR_MODE_HOST) {
> +		ret = 0;
> +		goto out;
> +	}
> +
> +	INIT_DELAYED_WORK(&rport->chg_work, rockchip_chg_detect_work);
> +	INIT_DELAYED_WORK(&rport->otg_sm_work, rockchip_usb2phy_otg_sm_work);
> +
> +	rport->utmi_avalid =
> +		of_property_read_bool(child_np, "rockchip,utmi-avalid");
> +
> +	rport->bvalid_irq = of_irq_get_byname(child_np, "otg-bvalid");
> +	if (rport->bvalid_irq < 0) {
> +		dev_err(rphy->dev, "no vbus valid irq provided\n");
> +		ret = rport->bvalid_irq;
> +		goto out;
> +	}
> +
> +	ret = devm_request_threaded_irq(rphy->dev, rport->bvalid_irq, NULL,
> +					rockchip_usb2phy_bvalid_irq,
> +					IRQF_ONESHOT,
> +					"rockchip_usb2phy_bvalid", rport);
> +	if (ret) {
> +		dev_err(rphy->dev, "failed to request otg-bvalid irq handle\n");
> +		goto out;
> +	}
> +
> +	if (!IS_ERR(rphy->edev)) {
> +		rport->event_nb.notifier_call = rockchip_otg_event;
> +
> +		ret = extcon_register_notifier(rphy->edev, EXTCON_USB_HOST,
> +					       &rport->event_nb);
> +		if (ret)
> +			dev_err(rphy->dev, "register USB HOST notifier failed\n");
> +	}
> +
> +out:
> +	return ret;
> +}
> +
>  static int rockchip_usb2phy_probe(struct platform_device *pdev)
>  {
>  	struct device *dev = &pdev->dev;
> @@ -553,8 +1045,14 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
>  
>  	rphy->dev = dev;
>  	phy_cfgs = match->data;
> +	rphy->chg_state = USB_CHG_STATE_UNDEFINED;
> +	rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN;
>  	platform_set_drvdata(pdev, rphy);
>  
> +	ret = rockchip_usb2phy_extcon_register(rphy);
> +	if (ret)
> +		return ret;
> +
>  	/* find out a proper config which can be matched with dt. */
>  	index = 0;
>  	while (phy_cfgs[index].reg) {
> @@ -591,13 +1089,9 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
>  		struct rockchip_usb2phy_port *rport = &rphy->ports[index];
>  		struct phy *phy;
>  
> -		/*
> -		 * This driver aim to support both otg-port and host-port,
> -		 * but unfortunately, the otg part is not ready in current,
> -		 * so this comments and below codes are interim, which should
> -		 * be changed after otg-port is supplied soon.
> -		 */
> -		if (of_node_cmp(child_np->name, "host-port"))
> +		/* This driver aims to support both otg-port and host-port */
> +		if (of_node_cmp(child_np->name, "host-port") &&
> +		    of_node_cmp(child_np->name, "otg-port"))
>  			goto next_child;
>  
>  		phy = devm_phy_create(dev, child_np, &rockchip_usb2phy_ops);
> @@ -610,9 +1104,18 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
>  		rport->phy = phy;
>  		phy_set_drvdata(rport->phy, rport);
>  
> -		ret = rockchip_usb2phy_host_port_init(rphy, rport, child_np);
> -		if (ret)
> -			goto put_child;
> +		/* initialize otg/host port separately */
> +		if (!of_node_cmp(child_np->name, "host-port")) {
> +			ret = rockchip_usb2phy_host_port_init(rphy, rport,
> +							      child_np);
> +			if (ret)
> +				goto put_child;
> +		} else {
> +			ret = rockchip_usb2phy_otg_port_init(rphy, rport,
> +							     child_np);
> +			if (ret)
> +				goto put_child;
> +		}
>  
>  next_child:
>  		/* to prevent out of boundary */
> @@ -654,10 +1157,18 @@ static const struct rockchip_usb2phy_cfg rk3366_phy_cfgs[] = {
>  
>  static const struct rockchip_usb2phy_cfg rk3399_phy_cfgs[] = {
>  	{
> -		.reg = 0xe450,
> +		.reg		= 0xe450,
>  		.num_ports	= 2,
>  		.clkout_ctl	= { 0xe450, 4, 4, 1, 0 },
>  		.port_cfgs	= {
> +			[USB2PHY_PORT_OTG] = {
> +				.phy_sus	= { 0xe454, 1, 0, 2, 1 },
> +				.bvalid_det_en	= { 0xe3c0, 3, 3, 0, 1 },
> +				.bvalid_det_st	= { 0xe3e0, 3, 3, 0, 1 },
> +				.bvalid_det_clr	= { 0xe3d0, 3, 3, 0, 1 },
> +				.utmi_avalid	= { 0xe2ac, 7, 7, 0, 1 },
> +				.utmi_bvalid	= { 0xe2ac, 12, 12, 0, 1 },
> +			},
>  			[USB2PHY_PORT_HOST] = {
>  				.phy_sus	= { 0xe458, 1, 0, 0x2, 0x1 },
>  				.ls_det_en	= { 0xe3c0, 6, 6, 0, 1 },
> @@ -667,12 +1178,32 @@ static const struct rockchip_usb2phy_cfg rk3399_phy_cfgs[] = {
>  				.utmi_hstdet	= { 0xe2ac, 23, 23, 0, 1 }
>  			}
>  		},
> +		.chg_det = {
> +			.opmode		= { 0xe454, 3, 0, 5, 1 },
> +			.cp_det		= { 0xe2ac, 2, 2, 0, 1 },
> +			.dcp_det	= { 0xe2ac, 1, 1, 0, 1 },
> +			.dp_det		= { 0xe2ac, 0, 0, 0, 1 },
> +			.idm_sink_en	= { 0xe450, 8, 8, 0, 1 },
> +			.idp_sink_en	= { 0xe450, 7, 7, 0, 1 },
> +			.idp_src_en	= { 0xe450, 9, 9, 0, 1 },
> +			.rdm_pdwn_en	= { 0xe450, 10, 10, 0, 1 },
> +			.vdm_src_en	= { 0xe450, 12, 12, 0, 1 },
> +			.vdp_src_en	= { 0xe450, 11, 11, 0, 1 },
> +		},
>  	},
>  	{
> -		.reg = 0xe460,
> +		.reg		= 0xe460,
>  		.num_ports	= 2,
>  		.clkout_ctl	= { 0xe460, 4, 4, 1, 0 },
>  		.port_cfgs	= {
> +			[USB2PHY_PORT_OTG] = {
> +				.phy_sus        = { 0xe464, 1, 0, 2, 1 },
> +				.bvalid_det_en  = { 0xe3c0, 8, 8, 0, 1 },
> +				.bvalid_det_st  = { 0xe3e0, 8, 8, 0, 1 },
> +				.bvalid_det_clr = { 0xe3d0, 8, 8, 0, 1 },
> +				.utmi_avalid	= { 0xe2ac, 10, 10, 0, 1 },
> +				.utmi_bvalid    = { 0xe2ac, 16, 16, 0, 1 },
> +			},
>  			[USB2PHY_PORT_HOST] = {
>  				.phy_sus	= { 0xe468, 1, 0, 0x2, 0x1 },
>  				.ls_det_en	= { 0xe3c0, 11, 11, 0, 1 },
> 

^ permalink raw reply

* [PATCH -next] phy: meson8b-usb2: fix missing clk_disable_unprepare() on error
From: Kishon Vijay Abraham I @ 2016-11-15 13:42 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477146822-31327-1-git-send-email-weiyj.lk@gmail.com>



On Saturday 22 October 2016 08:03 PM, Wei Yongjun wrote:
> From: Wei Yongjun <weiyongjun1@huawei.com>
> 
> Fix the missing clk_disable_unprepare() before return from
> phy_meson8b_usb2_power_on() in the error handling case.
> 
> Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>

merged, thanks.

-Kishon
> ---
>  drivers/phy/phy-meson8b-usb2.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/phy/phy-meson8b-usb2.c b/drivers/phy/phy-meson8b-usb2.c
> index 73bf632..dca3947 100644
> --- a/drivers/phy/phy-meson8b-usb2.c
> +++ b/drivers/phy/phy-meson8b-usb2.c
> @@ -158,6 +158,7 @@ static int phy_meson8b_usb2_power_on(struct phy *phy)
>  	ret = clk_prepare_enable(priv->clk_usb);
>  	if (ret) {
>  		dev_err(&phy->dev, "Failed to enable USB DDR clock\n");
> +		clk_disable_unprepare(priv->clk_usb_general);
>  		return ret;
>  	}
>  
> @@ -190,6 +191,8 @@ static int phy_meson8b_usb2_power_on(struct phy *phy)
>  		if (phy_meson8b_usb2_read(priv, REG_ADP_BC) &
>  			REG_ADP_BC_ACA_PIN_FLOAT) {
>  			dev_warn(&phy->dev, "USB ID detect failed!\n");
> +			clk_disable_unprepare(priv->clk_usb);
> +			clk_disable_unprepare(priv->clk_usb_general);
>  			return -EINVAL;
>  		}
>  	}
> 

^ permalink raw reply

* wdt, gpio: move arch_initcall into subsys_initcall ?
From: Guenter Roeck @ 2016-11-15 13:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <e4472c2d-effa-9583-aded-8dcdfdd57ee6@mentor.com>

On 11/15/2016 03:32 AM, Vladimir Zapolskiy wrote:
> On 11/15/2016 01:10 PM, Vladimir Zapolskiy wrote:
>> Hello Heiko,
>>
>> On 11/15/2016 12:20 PM, Heiko Schocher wrote:
>>> Hello,
>>>
>>> commit e188cbf7564f: "gpio: mxc: shift gpio_mxc_init() to subsys_initcall level"
>>> moves the gpio initialization of the mxc gpio driver
>>> from the arch_initcall level into subsys_initcall level.
>>>
>>> This leads now on mxc boards, which use a gpio wdt driver
>>> and the CONFIG_GPIO_WATCHDOG_ARCH_INITCALL option enabled,
>>> to unwanted driver probe deferrals during kernel boot.
>>>
>>> I see this currently on an imx6 based board (which has unfortunately
>>> 3 WDT: imx6 internal (disabled), gpio wdt and da9063 WDT ...).
>>>
>>> Also a side effect from above commit is, that the da9063 WDT driver
>>> is now probed before the gpio WDT driver ... so /dev/watchdog now
>>> does not point to the gpio_wdt, instead it points to the da9063 WDT.
>>>
>>> So there are 2 solutions possible:
>>>
>>> - add a CONFIG_GPIO_MCX_ARCH_INITCALL option
>>>   in drivers/gpio/gpio-mxc.c like for the gpio_wdt.c driver?
>>
>> in my opinion this is overly heavy solution and it might be
>> better to avoid it if possible.
>>
>> I would rather prefer to reconsider GPIO_WATCHDOG_ARCH_INITCALL
>> usage in the watchdog driver.
>>
>> Moreover adding this proposed GPIO_MCX_ARCH_INITCALL to call
>> the driver on arch level will result in deferring the GPIO driver.
>>
>>>   But how can we guarantee, that first the gpio driver and then
>>>   the gpio_wdt driver gets probed?
>>>
>>> - move the arch_initcall in gpio_wdt.c into a subsys_initcall
>>>   (Tested this, and the probe dereferral messages are gone ...)
>>>
>>>   But this may results in problems on boards, which needs an early
>>>   trigger on an gpio wdt ...
>>
>> The level of "earliness" can not be defined in absolute time value
>> in any case, why decreasing the init level of the watchdog driver
>> to subsys level can cause problems? For that there should exist
>> some kind of a dependency on IC or PCB hardware level, can you
>> name it please?
>>
>> Also please note that more than a half of all GPIO drivers settle
>> on subsys or later initcall level, this means that there is
>> an expected GPIO watchdog driver deferral for all of them.
>
> Please find two more late notes though.
>
>> I propose to send two patches for review:
>>
>> 1. remove GPIO_WATCHDOG_ARCH_INITCALL option completely and decouple
>>    module_platform_driver() into arch_initcall() and module_exit()
>>    unconditionally.
>>
>> 2. change arch_initcall() in the watchdog driver to subsys_initcall().
>>    This change removes probe deferrals on boot, when the driver is
>>    used with the most of the GPIO controllers.
>
> Alternatively commit 5e53c8ed813d ("watchdog: gpio_wdt: Add option for
> early registration") can be reverted and then module_platform_driver()
> is decoupled into subsys_initcall() and module_exit() as its replacement.
>
Sure, only the reason for that was that there are situations where
subsys_initcall() was too late. Also, when using arch_initcall() only,
we get deferrals again, which is apparently hated by many and a reason
for all those "avoid probe deferrals" patches.

> And also please note that since quite many GPIO controller drivers
> live on initcall levels after subsys_initcall(), the solution won't
> let to avoid watchdog driver deferrals totally, this should be accepted.
>
... except for others it isn't, and we are back to square one.

GPIO_WATCHDOG_ARCH_INITCALL was intended to be only used in situations
where needed. Why is it used here in the first place if that is not
the case ?

Guenter

^ permalink raw reply

* LEDs that change brightness "itself" -- that's a trigger. Re: PM regression with LED changes in next-20161109
From: Hans de Goede @ 2016-11-15 13:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <9e7d5e0f-c4ca-6930-63b9-83dc28517f33@samsung.com>

Hi,

On 15-11-16 14:28, Jacek Anaszewski wrote:
> On 11/15/2016 01:06 PM, Hans de Goede wrote:
>> Hi,
>>
>> On 15-11-16 12:48, Pavel Machek wrote:
>>> Hi!
>>>
>>>>>>> The LED you are talking about _has_ a trigger, implemented in
>>>>>>> hardware. That trigger can change LED brightness behind kernel's (and
>>>>>>> userspace's) back. Don't pretend the trigger does not exist, it does.
>>>>>>>
>>>>>>> And when you do that, you'll have nice place to report changes to
>>>>>>> userspace -- trigger can now export that information, and offer
>>>>>>> poll()
>>>>>>> interface.
>>>>>>
>>>>>> Well, that sounds interesting. It is logically justifiable.
>>>>>
>>>>> Thanks.
>>>>>
>>>>>> I initially proposed exactly this solution, with recently
>>>>>> added userspace LED being a trigger listener. It seems a bit
>>>>>> awkward though. How would you listen to the trigger events?
>>>>>
>>>>> Trigger exposes a file in sysfs, with poll() working on that file
>>>>
>>>> Hmm, a new file would give the advantage of making it easy for
>>>> userspace to see if the trigger is poll-able, this is likely
>>>> better then my own proposal I just send.
>>>
>>> Good.
>>>
>>>>> (and
>>>>> probably read exposing the current brightness).
>>>>
>>>> If we do this, can we please make it mirror brightness, iow
>>>> also make it writable, that will make it easier for userspace
>>>> to deal with it. We can simply re-use the existing show / store
>>>> methods for brightness for this.
>>>
>>> Actually, echo 0 > brightness disables the trigger, IIRC. I'd avoid
>>> that here, you want to be able to turn off the backlight but still
>>> keep the trigger (and be notified of future changes).
>>
>> True, that is easy to do the store method will just need to call
>> led_set_brightness_nosleep instead of led_set_brightness, this
>> will skip the checks to stop blinking in led_set_brightness and
>> otherwise is equivalent.
>>
>>>> I suggest we call it:
>>>>
>>>> trigger_brightness
>>>>
>>>> And only register it when a poll-able trigger is present.
>>>
>>> I'd call it 'current_brightness', but that's no big deal. Yes, only
>>> registering it for poll-able triggers makes sense.
>>
>> current_brightness works for me. I will take a shot a patch-set
>> implementing this.
>
> Word "current" is not precise here.
>
> It can be thought of as either last brightness set by the
> user or the brightness currently written to the device
> (returned by brightness file).
>
> There is a semantic discrepancy in our requirements -
> we want the file representing both permanent brightness
> set by the user and brightness set by the hardware.
>
> The two stand in contradiction to each other since
> brightness set by the user can be adjusted by the hardware.
>
> Reading the file shouldn't update brightness property of
> struct led_classdev, so it shouldn't call led_update_brightness()
> but it still should allow reading brightness set by the
> hardware, as a result of each POLLPRI event. So in fact in
> the same time it should report both according to our requirements
> which is impossible. Do we need three brightness files ?

I don't think so, current_brightness actually is an accurate
name, if the brightness was last changed by writing from
sysfs, the keyboard backlight will honor that and the current_brightness
attribute will show the brightness last set through writing it,
which matches the actual current brightness of the keyboard backlight.

Likewise if it was changed with the hotkey last then the keyboard
backlight brightness will be changed and reading from current_brightness
will return the new actual brightness. Basically reading from this
file will be no different then reading from the normal "brightness"
file the difference will be in that it is poll-able and that
writing 0 turns off the LED without stopping blinking.

Regards,

Hans

^ permalink raw reply

* [PATCH v3 1/3] phy_sun4i_usb: set_mode: Allow using set_mode to force end the current session
From: Kishon Vijay Abraham I @ 2016-11-15 13:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160923134058.26828-1-hdegoede@redhat.com>



On Friday 23 September 2016 07:10 PM, Hans de Goede wrote:
> The sunxi musb has a bug where sometimes it will generate a babble
> error on device disconnect instead of a disconnect irq. When this
> happens the musb-controller switches from host mode to device mode
> (it clears MUSB_DEVCTL_SESSION and sets MUSB_DEVCTL_BDEVICE) and
> gets stuck in this state.
> 
> Clearing this requires reporting Vbus low for 200 or more ms, but
> on some devices Vbus is simply always high (host-only mode, no Vbus
> control).
> 
> This commit modifies sun4i_usb_phy_set_mode so that it will force
> end the current session when called with the current mode, before this
> commit calling set_mode with the current mode was a nop since id_det
> would stay the same resulting in the detect_work not doing anything.
> 
> This allows the sunxi-musb glue to use sun4i_usb_phy_set_mode to force
> end the current session without changing the mode, to fixup the stuck
> state after a babble error.
> 
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>

merged, thanks.

-Kishon
> ---
> Changes in v2:
> -New patch in v2 of this series replacing the
>  "phy-sun4i-usb: Add sun4i_usb_phy_force_session_end() function"
>  from v1
> Changes in v3:
> -Fix dev_info so that it prints the new-mode instead of the old one
> ---
>  drivers/phy/phy-sun4i-usb.c | 14 ++++++++++----
>  1 file changed, 10 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c
> index 43c0d98..cbd338d 100644
> --- a/drivers/phy/phy-sun4i-usb.c
> +++ b/drivers/phy/phy-sun4i-usb.c
> @@ -437,25 +437,31 @@ static int sun4i_usb_phy_set_mode(struct phy *_phy, enum phy_mode mode)
>  {
>  	struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
>  	struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
> +	int new_mode;
>  
>  	if (phy->index != 0)
>  		return -EINVAL;
>  
>  	switch (mode) {
>  	case PHY_MODE_USB_HOST:
> -		data->dr_mode = USB_DR_MODE_HOST;
> +		new_mode = USB_DR_MODE_HOST;
>  		break;
>  	case PHY_MODE_USB_DEVICE:
> -		data->dr_mode = USB_DR_MODE_PERIPHERAL;
> +		new_mode = USB_DR_MODE_PERIPHERAL;
>  		break;
>  	case PHY_MODE_USB_OTG:
> -		data->dr_mode = USB_DR_MODE_OTG;
> +		new_mode = USB_DR_MODE_OTG;
>  		break;
>  	default:
>  		return -EINVAL;
>  	}
>  
> -	dev_info(&_phy->dev, "Changing dr_mode to %d\n", (int)data->dr_mode);
> +	if (new_mode != data->dr_mode) {
> +		dev_info(&_phy->dev, "Changing dr_mode to %d\n", new_mode);
> +		data->dr_mode = new_mode;
> +	}
> +
> +	data->id_det = -1; /* Force reprocessing of id */
>  	data->force_session_end = true;
>  	queue_delayed_work(system_wq, &data->detect, 0);
>  
> 

^ permalink raw reply

* [PATCH] ASoC: mioa701_wm9713: add missing white space in dev_err message
From: Lothar Waßmann @ 2016-11-15 13:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161112163025.4801-1-colin.king@canonical.com>

Hi,

On Sat, 12 Nov 2016 16:30:25 +0000 Colin King wrote:
> From: Colin Ian King <colin.king@canonical.com>
> 
> There is a missing whitespace in the dev_err message between
> "will" and "lead".  Add the whitespace.
> 
> Signed-off-by: Colin Ian King <colin.king@canonical.com>
> ---
>  sound/soc/pxa/mioa701_wm9713.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/sound/soc/pxa/mioa701_wm9713.c b/sound/soc/pxa/mioa701_wm9713.c
> index d1661fa..0fe0abe 100644
> --- a/sound/soc/pxa/mioa701_wm9713.c
> +++ b/sound/soc/pxa/mioa701_wm9713.c
> @@ -187,7 +187,7 @@ static int mioa701_wm9713_probe(struct platform_device *pdev)
>  	mioa701.dev = &pdev->dev;
>  	rc = devm_snd_soc_register_card(&pdev->dev, &mioa701);
>  	if (!rc)
> -		dev_warn(&pdev->dev, "Be warned that incorrect mixers/muxes setup will"
> +		dev_warn(&pdev->dev, "Be warned that incorrect mixers/muxes setup will "
>  			 "lead to overheating and possible destruction of your device."
>  			 " Do not use without a good knowledge of mio's board design!\n");
>
There is already a continuation line that has a whitespace in front. It
would be nice to be consistent and also add the missing whitespace in
front of the succeeding line...


Lothar Wa?mann

^ permalink raw reply

* [PATCH v2 0/3] ARM: dts: sun7i: BPI-M1+ USB support
From: Chen-Yu Tsai @ 2016-11-15 13:51 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Maxime,

These are the remaining patches of my BPI-M1+ fixes series from July.

Changes since v1:

  - Split out USB PHY enable patch.

  - Dropped custom OPP table. Tested the A20 default one with
    cpufreq-ljt-stress-test and it seemed stable.

  - Dropped voltage range for cpu supply regulator to normal 1.0V ~ 1.4V.

  - Dropped pinmux setting for OTG ID pin.


Please have a look.

Regards
ChenYu

Chen-Yu Tsai (3):
  ARM: dts: sun7i: bananapi-m1-plus: Enable USB PHY for USB host support
  ARM: dts: sun7i: bananapi-m1-plus: Add PMIC regulators
  ARM: dts: sun7i: bananapi-m1-plus: Enable USB OTG

 arch/arm/boot/dts/sun7i-a20-bananapi-m1-plus.dts | 60 ++++++++++++++++++++++--
 1 file changed, 56 insertions(+), 4 deletions(-)

-- 
2.10.2

^ permalink raw reply

* [PATCH v2 1/3] ARM: dts: sun7i: bananapi-m1-plus: Enable USB PHY for USB host support
From: Chen-Yu Tsai @ 2016-11-15 13:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161115135106.438-1-wens@csie.org>

The 2 USB host ports are directly tied to the 2 USB hosts in the SoC.
The 2 host pairs were already enabled, but the USB PHY wasn't.
VBUS on the 2 ports are always on.

Enable the USB PHY.

Fixes: 04c85ecad32a ("ARM: dts: sun7i: Add dts file for Bananapi M1 Plus
		      board")
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
---
 arch/arm/boot/dts/sun7i-a20-bananapi-m1-plus.dts | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/sun7i-a20-bananapi-m1-plus.dts b/arch/arm/boot/dts/sun7i-a20-bananapi-m1-plus.dts
index ba5bca0fe997..44377a98cc89 100644
--- a/arch/arm/boot/dts/sun7i-a20-bananapi-m1-plus.dts
+++ b/arch/arm/boot/dts/sun7i-a20-bananapi-m1-plus.dts
@@ -227,3 +227,8 @@
 	pinctrl-0 = <&uart0_pins_a>;
 	status = "okay";
 };
+
+&usbphy {
+	/* VBUS on usb host ports are tied to DC5V and therefore always on */
+	status = "okay";
+};
-- 
2.10.2

^ permalink raw reply related

* [PATCH v2 2/3] ARM: dts: sun7i: bananapi-m1-plus: Add PMIC regulators
From: Chen-Yu Tsai @ 2016-11-15 13:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161115135106.438-1-wens@csie.org>

The Bananapi M1+, like other Allwinner A20 based boards, uses the
AXP209 PMIC to supply its power.

Add the AXP209 regulators.

Signed-off-by: Chen-Yu Tsai <wens@csie.org>
---
 arch/arm/boot/dts/sun7i-a20-bananapi-m1-plus.dts | 35 +++++++++++++++++++++---
 1 file changed, 31 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/sun7i-a20-bananapi-m1-plus.dts b/arch/arm/boot/dts/sun7i-a20-bananapi-m1-plus.dts
index 44377a98cc89..ac19630c1c23 100644
--- a/arch/arm/boot/dts/sun7i-a20-bananapi-m1-plus.dts
+++ b/arch/arm/boot/dts/sun7i-a20-bananapi-m1-plus.dts
@@ -105,6 +105,10 @@
 	status = "okay";
 };
 
+&cpu0 {
+	cpu-supply = <&reg_dcdc2>;
+};
+
 &ehci0 {
 	status = "okay";
 };
@@ -132,16 +136,14 @@
 	status = "okay";
 
 	axp209: pmic at 34 {
-		compatible = "x-powers,axp209";
 		reg = <0x34>;
 		interrupt-parent = <&nmi_intc>;
 		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
-
-		interrupt-controller;
-		#interrupt-cells = <1>;
 	};
 };
 
+#include "axp209.dtsi"
+
 &ir0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&ir0_rx_pins_a>;
@@ -222,6 +224,31 @@
 	};
 };
 
+&reg_dcdc2 {
+	regulator-always-on;
+	regulator-min-microvolt = <1000000>;
+	regulator-max-microvolt = <1400000>;
+	regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc3 {
+	regulator-always-on;
+	regulator-min-microvolt = <1000000>;
+	regulator-max-microvolt = <1400000>;
+	regulator-name = "vdd-int-dll";
+};
+
+&reg_ldo1 {
+	regulator-name = "vdd-rtc";
+};
+
+&reg_ldo2 {
+	regulator-always-on;
+	regulator-min-microvolt = <3000000>;
+	regulator-max-microvolt = <3000000>;
+	regulator-name = "avcc";
+};
+
 &uart0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart0_pins_a>;
-- 
2.10.2

^ permalink raw reply related

* [PATCH v2 3/3] ARM: dts: sun7i: bananapi-m1-plus: Enable USB OTG
From: Chen-Yu Tsai @ 2016-11-15 13:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161115135106.438-1-wens@csie.org>

The Bananapi M1+ supports USB OTG, with the PMIC doing VBUS sensing.
Enable the USB OTG related functions.

Signed-off-by: Chen-Yu Tsai <wens@csie.org>
---
 arch/arm/boot/dts/sun7i-a20-bananapi-m1-plus.dts | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/arch/arm/boot/dts/sun7i-a20-bananapi-m1-plus.dts b/arch/arm/boot/dts/sun7i-a20-bananapi-m1-plus.dts
index ac19630c1c23..5f7114e13850 100644
--- a/arch/arm/boot/dts/sun7i-a20-bananapi-m1-plus.dts
+++ b/arch/arm/boot/dts/sun7i-a20-bananapi-m1-plus.dts
@@ -194,6 +194,10 @@
 	status = "okay";
 };
 
+&otg_sram {
+	status = "okay";
+};
+
 &pio {
 	gmac_power_pin_bpi_m1p: gmac_power_pin at 0 {
 		allwinner,pins = "PH23";
@@ -249,13 +253,29 @@
 	regulator-name = "avcc";
 };
 
+&reg_usb0_vbus {
+	status = "okay";
+};
+
 &uart0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart0_pins_a>;
 	status = "okay";
 };
 
+&usb_otg {
+	dr_mode = "otg";
+	status = "okay";
+};
+
+&usb_power_supply {
+	status = "okay";
+};
+
 &usbphy {
+	usb0_id_det-gpios = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */
+	usb0_vbus_power-supply = <&usb_power_supply>;
+	usb0_vbus-supply = <&reg_usb0_vbus>;
 	/* VBUS on usb host ports are tied to DC5V and therefore always on */
 	status = "okay";
 };
-- 
2.10.2

^ permalink raw reply related

* LEDs that change brightness "itself" -- that's a trigger. Re: PM regression with LED changes in next-20161109
From: Jacek Anaszewski @ 2016-11-15 14:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <9d42546d-5917-891c-2b18-ccf7f7328624@redhat.com>

On 11/15/2016 02:48 PM, Hans de Goede wrote:
> Hi,
>
> On 15-11-16 14:28, Jacek Anaszewski wrote:
>> On 11/15/2016 01:06 PM, Hans de Goede wrote:
>>> Hi,
>>>
>>> On 15-11-16 12:48, Pavel Machek wrote:
>>>> Hi!
>>>>
>>>>>>>> The LED you are talking about _has_ a trigger, implemented in
>>>>>>>> hardware. That trigger can change LED brightness behind kernel's
>>>>>>>> (and
>>>>>>>> userspace's) back. Don't pretend the trigger does not exist, it
>>>>>>>> does.
>>>>>>>>
>>>>>>>> And when you do that, you'll have nice place to report changes to
>>>>>>>> userspace -- trigger can now export that information, and offer
>>>>>>>> poll()
>>>>>>>> interface.
>>>>>>>
>>>>>>> Well, that sounds interesting. It is logically justifiable.
>>>>>>
>>>>>> Thanks.
>>>>>>
>>>>>>> I initially proposed exactly this solution, with recently
>>>>>>> added userspace LED being a trigger listener. It seems a bit
>>>>>>> awkward though. How would you listen to the trigger events?
>>>>>>
>>>>>> Trigger exposes a file in sysfs, with poll() working on that file
>>>>>
>>>>> Hmm, a new file would give the advantage of making it easy for
>>>>> userspace to see if the trigger is poll-able, this is likely
>>>>> better then my own proposal I just send.
>>>>
>>>> Good.
>>>>
>>>>>> (and
>>>>>> probably read exposing the current brightness).
>>>>>
>>>>> If we do this, can we please make it mirror brightness, iow
>>>>> also make it writable, that will make it easier for userspace
>>>>> to deal with it. We can simply re-use the existing show / store
>>>>> methods for brightness for this.
>>>>
>>>> Actually, echo 0 > brightness disables the trigger, IIRC. I'd avoid
>>>> that here, you want to be able to turn off the backlight but still
>>>> keep the trigger (and be notified of future changes).
>>>
>>> True, that is easy to do the store method will just need to call
>>> led_set_brightness_nosleep instead of led_set_brightness, this
>>> will skip the checks to stop blinking in led_set_brightness and
>>> otherwise is equivalent.
>>>
>>>>> I suggest we call it:
>>>>>
>>>>> trigger_brightness
>>>>>
>>>>> And only register it when a poll-able trigger is present.
>>>>
>>>> I'd call it 'current_brightness', but that's no big deal. Yes, only
>>>> registering it for poll-able triggers makes sense.
>>>
>>> current_brightness works for me. I will take a shot a patch-set
>>> implementing this.
>>
>> Word "current" is not precise here.
>>
>> It can be thought of as either last brightness set by the
>> user or the brightness currently written to the device
>> (returned by brightness file).
>>
>> There is a semantic discrepancy in our requirements -
>> we want the file representing both permanent brightness
>> set by the user and brightness set by the hardware.
>>
>> The two stand in contradiction to each other since
>> brightness set by the user can be adjusted by the hardware.
>>
>> Reading the file shouldn't update brightness property of
>> struct led_classdev, so it shouldn't call led_update_brightness()
>> but it still should allow reading brightness set by the
>> hardware, as a result of each POLLPRI event. So in fact in
>> the same time it should report both according to our requirements
>> which is impossible. Do we need three brightness files ?
>
> I don't think so, current_brightness actually is an accurate
> name, if the brightness was last changed by writing from
> sysfs, the keyboard backlight will honor that and the current_brightness
> attribute will show the brightness last set through writing it,
> which matches the actual current brightness of the keyboard backlight.
>
> Likewise if it was changed with the hotkey last then the keyboard
> backlight brightness will be changed and reading from current_brightness
> will return the new actual brightness. Basically reading from this
> file will be no different then reading from the normal "brightness"
> file the difference will be in that it is poll-able and that
> writing 0 turns off the LED without stopping blinking.

If so then when software blinking enabled, it will return 0 on low
blink cycle no matter what current brightness level is.

-- 
Best regards,
Jacek Anaszewski

^ permalink raw reply

* [PATCH] ARM64: zynqmp: Fix W=1 dtc 1.4 warnings
From: Michal Simek @ 2016-11-15 14:04 UTC (permalink / raw)
  To: linux-arm-kernel

The patch removes these warnings reported by dtc 1.4:
Warning (unit_address_vs_reg): Node /amba_apu has a reg or ranges
property, but no unit name
Warning (unit_address_vs_reg): Node /memory has a reg or ranges
property, but no unit name

Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---

 arch/arm64/boot/dts/xilinx/zynqmp-ep108.dts | 2 +-
 arch/arm64/boot/dts/xilinx/zynqmp.dtsi      | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-ep108.dts b/arch/arm64/boot/dts/xilinx/zynqmp-ep108.dts
index 358089687a69..ef1b9e573af0 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp-ep108.dts
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-ep108.dts
@@ -27,7 +27,7 @@
 		stdout-path = "serial0:115200n8";
 	};
 
-	memory {
+	memory at 0 {
 		device_type = "memory";
 		reg = <0x0 0x0 0x0 0x40000000>;
 	};
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
index 68a908334c7b..83791eadff41 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
+++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
@@ -72,7 +72,7 @@
 			     <1 10 0xf08>;
 	};
 
-	amba_apu {
+	amba_apu: amba_apu at 0 {
 		compatible = "simple-bus";
 		#address-cells = <2>;
 		#size-cells = <1>;
-- 
1.9.1

^ permalink raw reply related

* [PATCH 1/2] ARM: zynq: Remove skeleton.dtsi
From: Michal Simek @ 2016-11-15 14:07 UTC (permalink / raw)
  To: linux-arm-kernel

Based on
"ARM: dts: explicitly mark skeleton.dtsi as deprecated"
(sha1: 9c0da3cc61f1233c2782e2d3d91e3d0707dd4ba5)
skeleton.dtsi is deprecated.
Move address and size-cells directly to zynq-7000.dtsi.

Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---

 arch/arm/boot/dts/zynq-7000.dtsi | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/zynq-7000.dtsi b/arch/arm/boot/dts/zynq-7000.dtsi
index f283ff08381c..f47a6c1cc752 100644
--- a/arch/arm/boot/dts/zynq-7000.dtsi
+++ b/arch/arm/boot/dts/zynq-7000.dtsi
@@ -10,9 +10,10 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  */
-/include/ "skeleton.dtsi"
 
 / {
+	#address-cells = <1>;
+	#size-cells = <1>;
 	compatible = "xlnx,zynq-7000";
 
 	cpus {
-- 
1.9.1

^ permalink raw reply related

* [PATCH 2/2] ARM: zynq: Fix W=1 dtc 1.4 warnings
From: Michal Simek @ 2016-11-15 14:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <2d42e25d7dd03e562e12e71fd037837737115940.1479218844.git.michal.simek@xilinx.com>

The patch removes these warnings reported by dtc 1.4:
Warning (unit_address_vs_reg): Node /pmu has a reg or ranges property,
but no unit name
Warning (unit_address_vs_reg): Node /fixedregulator at 0 has a unit name,
but no reg property
Warning (unit_address_vs_reg): Node /memory has a reg or ranges
property, but no unit name

Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---

 arch/arm/boot/dts/zynq-7000.dtsi      | 4 ++--
 arch/arm/boot/dts/zynq-parallella.dts | 2 +-
 arch/arm/boot/dts/zynq-zc702.dts      | 2 +-
 arch/arm/boot/dts/zynq-zc706.dts      | 2 +-
 arch/arm/boot/dts/zynq-zed.dts        | 2 +-
 arch/arm/boot/dts/zynq-zybo.dts       | 2 +-
 6 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/arm/boot/dts/zynq-7000.dtsi b/arch/arm/boot/dts/zynq-7000.dtsi
index f47a6c1cc752..402b5bbe3b5b 100644
--- a/arch/arm/boot/dts/zynq-7000.dtsi
+++ b/arch/arm/boot/dts/zynq-7000.dtsi
@@ -42,14 +42,14 @@
 		};
 	};
 
-	pmu {
+	pmu at f8891000 {
 		compatible = "arm,cortex-a9-pmu";
 		interrupts = <0 5 4>, <0 6 4>;
 		interrupt-parent = <&intc>;
 		reg = < 0xf8891000 0x1000 0xf8893000 0x1000 >;
 	};
 
-	regulator_vccpint: fixedregulator at 0 {
+	regulator_vccpint: fixedregulator {
 		compatible = "regulator-fixed";
 		regulator-name = "VCCPINT";
 		regulator-min-microvolt = <1000000>;
diff --git a/arch/arm/boot/dts/zynq-parallella.dts b/arch/arm/boot/dts/zynq-parallella.dts
index 307ed201d658..64a6390fc501 100644
--- a/arch/arm/boot/dts/zynq-parallella.dts
+++ b/arch/arm/boot/dts/zynq-parallella.dts
@@ -28,7 +28,7 @@
 		serial0 = &uart1;
 	};
 
-	memory {
+	memory at 0 {
 		device_type = "memory";
 		reg = <0x0 0x40000000>;
 	};
diff --git a/arch/arm/boot/dts/zynq-zc702.dts b/arch/arm/boot/dts/zynq-zc702.dts
index e96959b2e67a..0cdad2cc8b78 100644
--- a/arch/arm/boot/dts/zynq-zc702.dts
+++ b/arch/arm/boot/dts/zynq-zc702.dts
@@ -24,7 +24,7 @@
 		serial0 = &uart1;
 	};
 
-	memory {
+	memory at 0 {
 		device_type = "memory";
 		reg = <0x0 0x40000000>;
 	};
diff --git a/arch/arm/boot/dts/zynq-zc706.dts b/arch/arm/boot/dts/zynq-zc706.dts
index be6a986bbbd8..ad4bb06dba25 100644
--- a/arch/arm/boot/dts/zynq-zc706.dts
+++ b/arch/arm/boot/dts/zynq-zc706.dts
@@ -24,7 +24,7 @@
 		serial0 = &uart1;
 	};
 
-	memory {
+	memory at 0 {
 		device_type = "memory";
 		reg = <0x0 0x40000000>;
 	};
diff --git a/arch/arm/boot/dts/zynq-zed.dts b/arch/arm/boot/dts/zynq-zed.dts
index 7250c1eac7f9..325379f7983c 100644
--- a/arch/arm/boot/dts/zynq-zed.dts
+++ b/arch/arm/boot/dts/zynq-zed.dts
@@ -23,7 +23,7 @@
 		serial0 = &uart1;
 	};
 
-	memory {
+	memory at 0 {
 		device_type = "memory";
 		reg = <0x0 0x20000000>;
 	};
diff --git a/arch/arm/boot/dts/zynq-zybo.dts b/arch/arm/boot/dts/zynq-zybo.dts
index d9e0f3e70671..590ec24b8749 100644
--- a/arch/arm/boot/dts/zynq-zybo.dts
+++ b/arch/arm/boot/dts/zynq-zybo.dts
@@ -23,7 +23,7 @@
 		serial0 = &uart1;
 	};
 
-	memory {
+	memory at 0 {
 		device_type = "memory";
 		reg = <0x0 0x20000000>;
 	};
-- 
1.9.1

^ permalink raw reply related

* [PATCH v7 00/16] ACPI IORT ARM SMMU support
From: Lorenzo Pieralisi @ 2016-11-15 14:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAJZ5v0gh9qB41zcnvnETDA-5ho577uhxE4rehZqEXorFViY__w@mail.gmail.com>

On Tue, Nov 15, 2016 at 02:04:09PM +0100, Rafael J. Wysocki wrote:
> On Tue, Nov 15, 2016 at 11:12 AM, Lorenzo Pieralisi
> <lorenzo.pieralisi@arm.com> wrote:
> > Hi Rafael,
> >
> > On Thu, Nov 10, 2016 at 12:36:12AM +0100, Rafael J. Wysocki wrote:
> >> Hi Lorenzo,
> >>
> >> On Wed, Nov 9, 2016 at 3:19 PM, Lorenzo Pieralisi
> >> <lorenzo.pieralisi@arm.com> wrote:
> >> > This patch series is v7 of a previous posting:
> >> >
> >> > https://lkml.org/lkml/2016/10/18/506
> >>
> >> I don't see anything objectionable in this series.
> >>
> >> Please let me know which patches in particular to look at in detail.
> >
> > Are patches 7 and consequently 16 (that builds on top of 7) ok with
> > you ? They should be equivalent to nop on anything other than ARM64
> > but they touch ACPI core so they require an ACK if they are ok please.
> 
> Yes, they are.  Please feel free to add my ACKs to those or I will
> send them separately later today.

Thank you very much, I will add them to v8 that should be final,
I will send it when the dust has settled on patch 4, which looks
like the last bit to sort out (we may not even need a v8 at all).

Thanks !
Lorenzo

^ permalink raw reply

* [PATCH/RESEND] recordmcount: arm: Implement make_nop
From: Ard Biesheuvel @ 2016-11-15 14:19 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161018234200.5804-1-sboyd@codeaurora.org>

On 19 October 2016 at 00:42, Stephen Boyd <sboyd@codeaurora.org> wrote:
> In similar spirit to x86 and arm64 support, add a make_nop_arm()
> to replace calls to mcount with a nop in sections that aren't
> traced.
>
> Cc: Russell King <linux@arm.linux.org.uk>
> Acked-by: Rabin Vincent <rabin@rab.in>
> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
> ---
>  scripts/recordmcount.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 65 insertions(+)
>
> diff --git a/scripts/recordmcount.c b/scripts/recordmcount.c
> index 5423a58d1b06..aeb34223167c 100644
> --- a/scripts/recordmcount.c
> +++ b/scripts/recordmcount.c
> @@ -213,6 +213,59 @@ static int make_nop_x86(void *map, size_t const offset)
>         return 0;
>  }
>
> +static unsigned char ideal_nop4_arm_le[4] = { 0x00, 0x00, 0xa0, 0xe1 }; /* mov r0, r0 */
> +static unsigned char ideal_nop4_arm_be[4] = { 0xe1, 0xa0, 0x00, 0x00 }; /* mov r0, r0 */

Shouldn't you be taking the difference between BE8 and BE32 into
account here? IIRC, BE8 uses little endian encoding for instructions.

> +static unsigned char *ideal_nop4_arm;
> +
> +static unsigned char bl_mcount_arm_le[4] = { 0xfe, 0xff, 0xff, 0xeb }; /* bl */
> +static unsigned char bl_mcount_arm_be[4] = { 0xeb, 0xff, 0xff, 0xfe }; /* bl */
> +static unsigned char *bl_mcount_arm;
> +
> +static unsigned char push_arm_le[4] = { 0x04, 0xe0, 0x2d, 0xe5 }; /* push {lr} */
> +static unsigned char push_arm_be[4] = { 0xe5, 0x2d, 0xe0, 0x04 }; /* push {lr} */
> +static unsigned char *push_arm;
> +
> +static unsigned char ideal_nop2_thumb_le[2] = { 0x00, 0xbf }; /* nop */
> +static unsigned char ideal_nop2_thumb_be[2] = { 0xbf, 0x00 }; /* nop */
> +static unsigned char *ideal_nop2_thumb;
> +
> +static unsigned char push_bl_mcount_thumb_le[6] = { 0x00, 0xb5, 0xff, 0xf7, 0xfe, 0xff }; /* push {lr}, bl */
> +static unsigned char push_bl_mcount_thumb_be[6] = { 0xb5, 0x00, 0xf7, 0xff, 0xff, 0xfe }; /* push {lr}, bl */
> +static unsigned char *push_bl_mcount_thumb;
> +
> +static int make_nop_arm(void *map, size_t const offset)
> +{
> +       char *ptr;
> +       int cnt = 1;
> +       int nop_size;
> +       size_t off = offset;
> +
> +       ptr = map + offset;
> +       if (memcmp(ptr, bl_mcount_arm, 4) == 0) {
> +               if (memcmp(ptr - 4, push_arm, 4) == 0) {
> +                       off -= 4;
> +                       cnt = 2;
> +               }
> +               ideal_nop = ideal_nop4_arm;
> +               nop_size = 4;
> +       } else if (memcmp(ptr - 2, push_bl_mcount_thumb, 6) == 0) {
> +               cnt = 3;
> +               nop_size = 2;
> +               off -= 2;
> +               ideal_nop = ideal_nop2_thumb;
> +       } else
> +               return -1;
> +
> +       /* Convert to nop */
> +       ulseek(fd_map, off, SEEK_SET);
> +
> +       do {
> +               uwrite(fd_map, ideal_nop, nop_size);
> +       } while (--cnt > 0);
> +
> +       return 0;
> +}
> +
>  static unsigned char ideal_nop4_arm64[4] = {0x1f, 0x20, 0x03, 0xd5};
>  static int make_nop_arm64(void *map, size_t const offset)
>  {
> @@ -430,6 +483,11 @@ do_file(char const *const fname)
>                         w2 = w2rev;
>                         w8 = w8rev;
>                 }
> +               ideal_nop4_arm = ideal_nop4_arm_le;
> +               bl_mcount_arm = bl_mcount_arm_le;
> +               push_arm = push_arm_le;
> +               ideal_nop2_thumb = ideal_nop2_thumb_le;
> +               push_bl_mcount_thumb = push_bl_mcount_thumb_le;
>                 break;
>         case ELFDATA2MSB:
>                 if (*(unsigned char const *)&endian != 0) {
> @@ -438,6 +496,11 @@ do_file(char const *const fname)
>                         w2 = w2rev;
>                         w8 = w8rev;
>                 }
> +               ideal_nop4_arm = ideal_nop4_arm_be;
> +               bl_mcount_arm = bl_mcount_arm_be;
> +               push_arm = push_arm_be;
> +               ideal_nop2_thumb = ideal_nop2_thumb_be;
> +               push_bl_mcount_thumb = push_bl_mcount_thumb_be;
>                 break;
>         }  /* end switch */
>         if (memcmp(ELFMAG, ehdr->e_ident, SELFMAG) != 0
> @@ -463,6 +526,8 @@ do_file(char const *const fname)
>                 break;
>         case EM_ARM:     reltype = R_ARM_ABS32;
>                          altmcount = "__gnu_mcount_nc";
> +                        make_nop = make_nop_arm;
> +                        rel_type_nop = R_ARM_NONE;
>                          break;
>         case EM_AARCH64:
>                         reltype = R_AARCH64_ABS64;
> --
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [GIT PULL] STM32 SOC changes for v4.10 #1
From: Alexandre Torgue @ 2016-11-15 14:22 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Olof, Arnd and Kevin,

Please consider this first round of STM32 SOC updates for v4.10:

The following changes since commit 1001354ca34179f3db924eb66672442a173147dc:

   Linux 4.9-rc1 (2016-10-15 12:17:50 -0700)

are available in the git repository at:

   git://git.kernel.org/pub/scm/linux/kernel/git/atorgue/stm32.git 
tags/soc-for-4.10-1

for you to fetch changes up to 6bc18b83c0c3b5d56137a31ce98ca2802036e7a9:

   ARM: Kconfig: Introduce MACH_STM32F746 flag (2016-11-15 12:02:59 +0100)

----------------------------------------------------------------
STM32 SOC updates for v4.10, round 1.

Highlights:
----------
  - Add new MCU SOC STM32F746

----------------------------------------------------------------
Alexandre TORGUE (2):
       ARM: mach-stm32: Add a new SOC - STM32F746
       ARM: Kconfig: Introduce MACH_STM32F746 flag

  Documentation/arm/stm32/overview.txt           |  3 ++-
  Documentation/arm/stm32/stm32f746-overview.txt | 34 
++++++++++++++++++++++++++
  arch/arm/Kconfig                               |  5 ++++
  arch/arm/mach-stm32/board-dt.c                 |  1 +
  4 files changed, 42 insertions(+), 1 deletion(-)
  create mode 100644 Documentation/arm/stm32/stm32f746-overview.txt

^ permalink raw reply

* [PATCH] arm/arm64: KVM: VGIC: limit ITARGETSR bits to number of VCPUs
From: Andre Przywara @ 2016-11-15 14:27 UTC (permalink / raw)
  To: linux-arm-kernel

The GICv2 spec says in section 4.3.12 that a "CPU targets field bit that
corresponds to an unimplemented CPU interface is RAZ/WI."
Currently we allow the guest to write any value in there and it can
read that back.
Mask the written value with the proper CPU mask to be spec compliant.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
---
 virt/kvm/arm/vgic/vgic-mmio-v2.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/virt/kvm/arm/vgic/vgic-mmio-v2.c b/virt/kvm/arm/vgic/vgic-mmio-v2.c
index b44b359..e59d4c7 100644
--- a/virt/kvm/arm/vgic/vgic-mmio-v2.c
+++ b/virt/kvm/arm/vgic/vgic-mmio-v2.c
@@ -129,6 +129,7 @@ static void vgic_mmio_write_target(struct kvm_vcpu *vcpu,
 				   unsigned long val)
 {
 	u32 intid = VGIC_ADDR_TO_INTID(addr, 8);
+	u8 cpu_mask = (1 << atomic_read(&vcpu->kvm->online_vcpus)) - 1;
 	int i;
 
 	/* GICD_ITARGETSR[0-7] are read-only */
@@ -141,7 +142,7 @@ static void vgic_mmio_write_target(struct kvm_vcpu *vcpu,
 
 		spin_lock(&irq->irq_lock);
 
-		irq->targets = (val >> (i * 8)) & 0xff;
+		irq->targets = ((val >> (i * 8)) & 0xff) & cpu_mask;
 		target = irq->targets ? __ffs(irq->targets) : 0;
 		irq->target_vcpu = kvm_get_vcpu(vcpu->kvm, target);
 
-- 
2.9.0

^ permalink raw reply related

* [PATCH net 0/3] Fix OdroidC2 Gigabit Tx link issue
From: Jerome Brunet @ 2016-11-15 14:29 UTC (permalink / raw)
  To: linux-arm-kernel

This patchset fixes an issue with the OdroidC2 board (DWMAC + RTL8211F).
Initially reported as a low Tx throughput issue at gigabit speed, the
platform enters LPI too often. This eventually break the link (both Tx
and Rx), and require to bring the interface down and up again to get the
Rx path working again.

The root cause of this issue is not fully understood yet but disabling EEE
advertisement on the PHY prevent this feature to be negotiated.
With this change, the link is stable and reliable, with the expected
throughput performance.

The patchset adds options in the realtek phy driver to disable EEE
advertisement, through device tree, for the phy version supporting EEE.
Then EEE is disabled in the OdroidC2 device tree for Gigabit speed.
100M is not affected by this issue.

Jerome Brunet (3):
  net: phy: realtek: add eee advertisement disable options
  dt-bindings: net: add DT bindings for realtek phys
  ARM64: dts: meson: odroidc2: disable 1000t-eee advertisement

 .../devicetree/bindings/net/realtek-phy.txt        | 20 +++++++
 .../arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts | 15 +++++
 drivers/net/phy/realtek.c                          | 65 +++++++++++++++++++++-
 3 files changed, 99 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/net/realtek-phy.txt

-- 
2.7.4

^ permalink raw reply

* [PATCH net 1/3] net: phy: realtek: add eee advertisement disable options
From: Jerome Brunet @ 2016-11-15 14:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1479220154-25851-1-git-send-email-jbrunet@baylibre.com>

On some platforms, energy efficient ethernet with rtl8211 devices is
causing issue, like throughput drop or broken link.

This was reported on the OdroidC2 (DWMAC + RTL8211F). While the issue root
cause is not fully understood yet, disabling EEE advertisement prevent auto
negotiation from enabling EEE.

This patch provides options to disable 1000T and 100TX EEE advertisement
individually for the realtek phys supporting this feature.

Reported-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Cc: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Cc: Alexandre TORGUE <alexandre.torgue@st.com>
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Tested-by: Andre Roth <neolynx@gmail.com>
---
 drivers/net/phy/realtek.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 64 insertions(+), 1 deletion(-)

diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index aadd6e9f54ad..77235fd5faaf 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -15,6 +15,12 @@
  */
 #include <linux/phy.h>
 #include <linux/module.h>
+#include <linux/of.h>
+
+struct rtl8211x_phy_priv {
+	bool eee_1000t_disable;
+	bool eee_100tx_disable;
+};
 
 #define RTL821x_PHYSR		0x11
 #define RTL821x_PHYSR_DUPLEX	0x2000
@@ -93,12 +99,44 @@ static int rtl8211f_config_intr(struct phy_device *phydev)
 	return err;
 }
 
+static void rtl8211x_clear_eee_adv(struct phy_device *phydev)
+{
+	struct rtl8211x_phy_priv *priv = phydev->priv;
+	u16 val;
+
+	if (priv->eee_1000t_disable || priv->eee_100tx_disable) {
+		val = phy_read_mmd_indirect(phydev, MDIO_AN_EEE_ADV,
+					    MDIO_MMD_AN);
+
+		if (priv->eee_1000t_disable)
+			val &= ~MDIO_AN_EEE_ADV_1000T;
+		if (priv->eee_100tx_disable)
+			val &= ~MDIO_AN_EEE_ADV_100TX;
+
+		phy_write_mmd_indirect(phydev, MDIO_AN_EEE_ADV,
+				       MDIO_MMD_AN, val);
+	}
+}
+
+static int rtl8211x_config_init(struct phy_device *phydev)
+{
+	int ret;
+
+	ret = genphy_config_init(phydev);
+	if (ret < 0)
+		return ret;
+
+	rtl8211x_clear_eee_adv(phydev);
+
+	return 0;
+}
+
 static int rtl8211f_config_init(struct phy_device *phydev)
 {
 	int ret;
 	u16 reg;
 
-	ret = genphy_config_init(phydev);
+	ret = rtl8211x_config_init(phydev);
 	if (ret < 0)
 		return ret;
 
@@ -115,6 +153,26 @@ static int rtl8211f_config_init(struct phy_device *phydev)
 	return 0;
 }
 
+static int rtl8211x_phy_probe(struct phy_device *phydev)
+{
+	struct device *dev = &phydev->mdio.dev;
+	struct device_node *of_node = dev->of_node;
+	struct rtl8211x_phy_priv *priv;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->eee_1000t_disable =
+		of_property_read_bool(of_node, "realtek,disable-eee-1000t");
+	priv->eee_100tx_disable =
+		of_property_read_bool(of_node, "realtek,disable-eee-100tx");
+
+	phydev->priv = priv;
+
+	return 0;
+}
+
 static struct phy_driver realtek_drvs[] = {
 	{
 		.phy_id         = 0x00008201,
@@ -140,7 +198,9 @@ static struct phy_driver realtek_drvs[] = {
 		.phy_id_mask	= 0x001fffff,
 		.features	= PHY_GBIT_FEATURES,
 		.flags		= PHY_HAS_INTERRUPT,
+		.probe		= &rtl8211x_phy_probe,
 		.config_aneg	= genphy_config_aneg,
+		.config_init	= &rtl8211x_config_init,
 		.read_status	= genphy_read_status,
 		.ack_interrupt	= rtl821x_ack_interrupt,
 		.config_intr	= rtl8211e_config_intr,
@@ -152,7 +212,9 @@ static struct phy_driver realtek_drvs[] = {
 		.phy_id_mask	= 0x001fffff,
 		.features	= PHY_GBIT_FEATURES,
 		.flags		= PHY_HAS_INTERRUPT,
+		.probe		= &rtl8211x_phy_probe,
 		.config_aneg	= &genphy_config_aneg,
+		.config_init	= &rtl8211x_config_init,
 		.read_status	= &genphy_read_status,
 		.ack_interrupt	= &rtl821x_ack_interrupt,
 		.config_intr	= &rtl8211e_config_intr,
@@ -164,6 +226,7 @@ static struct phy_driver realtek_drvs[] = {
 		.phy_id_mask	= 0x001fffff,
 		.features	= PHY_GBIT_FEATURES,
 		.flags		= PHY_HAS_INTERRUPT,
+		.probe		= &rtl8211x_phy_probe,
 		.config_aneg	= &genphy_config_aneg,
 		.config_init	= &rtl8211f_config_init,
 		.read_status	= &genphy_read_status,
-- 
2.7.4

^ permalink raw reply related

* [PATCH net 2/3] dt-bindings: net: add DT bindings for realtek phys
From: Jerome Brunet @ 2016-11-15 14:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1479220154-25851-1-git-send-email-jbrunet@baylibre.com>

Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 .../devicetree/bindings/net/realtek-phy.txt          | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/realtek-phy.txt

diff --git a/Documentation/devicetree/bindings/net/realtek-phy.txt b/Documentation/devicetree/bindings/net/realtek-phy.txt
new file mode 100644
index 000000000000..dc2845a6b387
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/realtek-phy.txt
@@ -0,0 +1,20 @@
+Realtek Ethernet PHY
+
+Some boards require special tuning values of the phy.
+
+Optional properties:
+
+realtek,disable-eee-1000t:
+realtek,disable-eee-100tx:
+  If set, respectively disable 1000-BaseT and 100-BaseTx energy efficient
+  ethernet capabilty advertisement
+  default: Leave the phy default settings unchanged (capabilities advertised)
+
+Example:
+
+&mdio0 {
+	ethernetphy0: ethernet-phy at 0 {
+		reg = <0>;
+		realtek,disable-eee-1000t;
+	};
+};
-- 
2.7.4

^ permalink raw reply related

* [PATCH net 3/3] ARM64: dts: meson: odroidc2: disable 1000t-eee advertisement
From: Jerome Brunet @ 2016-11-15 14:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1479220154-25851-1-git-send-email-jbrunet@baylibre.com>

Reported-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Cc: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Cc: Alexandre TORGUE <alexandre.torgue@st.com>
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Tested-by: Andre Roth <neolynx@gmail.com>
---
 arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
index e6e3491d48a5..1f4416ecb183 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
@@ -98,3 +98,18 @@
 	pinctrl-0 = <&i2c_a_pins>;
 	pinctrl-names = "default";
 };
+
+&ethmac {
+	phy-handle = <&eth_phy0>;
+
+	mdio {
+		compatible = "snps,dwmac-mdio";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		eth_phy0: ethernet-phy at 0 {
+			reg = <0>;
+			realtek,disable-eee-1000t;
+		};
+	};
+};
-- 
2.7.4

^ permalink raw reply related

* LEDs that change brightness "itself" -- that's a trigger. Re: PM regression with LED changes in next-20161109
From: Hans de Goede @ 2016-11-15 14:30 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <3bb538bb-3c80-70c7-2c44-46b174c90503@samsung.com>

Hi,

On 15-11-16 15:04, Jacek Anaszewski wrote:
> On 11/15/2016 02:48 PM, Hans de Goede wrote:
>> Hi,
>>
>> On 15-11-16 14:28, Jacek Anaszewski wrote:
>>> On 11/15/2016 01:06 PM, Hans de Goede wrote:
>>>> Hi,
>>>>
>>>> On 15-11-16 12:48, Pavel Machek wrote:
>>>>> Hi!
>>>>>
>>>>>>>>> The LED you are talking about _has_ a trigger, implemented in
>>>>>>>>> hardware. That trigger can change LED brightness behind kernel's
>>>>>>>>> (and
>>>>>>>>> userspace's) back. Don't pretend the trigger does not exist, it
>>>>>>>>> does.
>>>>>>>>>
>>>>>>>>> And when you do that, you'll have nice place to report changes to
>>>>>>>>> userspace -- trigger can now export that information, and offer
>>>>>>>>> poll()
>>>>>>>>> interface.
>>>>>>>>
>>>>>>>> Well, that sounds interesting. It is logically justifiable.
>>>>>>>
>>>>>>> Thanks.
>>>>>>>
>>>>>>>> I initially proposed exactly this solution, with recently
>>>>>>>> added userspace LED being a trigger listener. It seems a bit
>>>>>>>> awkward though. How would you listen to the trigger events?
>>>>>>>
>>>>>>> Trigger exposes a file in sysfs, with poll() working on that file
>>>>>>
>>>>>> Hmm, a new file would give the advantage of making it easy for
>>>>>> userspace to see if the trigger is poll-able, this is likely
>>>>>> better then my own proposal I just send.
>>>>>
>>>>> Good.
>>>>>
>>>>>>> (and
>>>>>>> probably read exposing the current brightness).
>>>>>>
>>>>>> If we do this, can we please make it mirror brightness, iow
>>>>>> also make it writable, that will make it easier for userspace
>>>>>> to deal with it. We can simply re-use the existing show / store
>>>>>> methods for brightness for this.
>>>>>
>>>>> Actually, echo 0 > brightness disables the trigger, IIRC. I'd avoid
>>>>> that here, you want to be able to turn off the backlight but still
>>>>> keep the trigger (and be notified of future changes).
>>>>
>>>> True, that is easy to do the store method will just need to call
>>>> led_set_brightness_nosleep instead of led_set_brightness, this
>>>> will skip the checks to stop blinking in led_set_brightness and
>>>> otherwise is equivalent.
>>>>
>>>>>> I suggest we call it:
>>>>>>
>>>>>> trigger_brightness
>>>>>>
>>>>>> And only register it when a poll-able trigger is present.
>>>>>
>>>>> I'd call it 'current_brightness', but that's no big deal. Yes, only
>>>>> registering it for poll-able triggers makes sense.
>>>>
>>>> current_brightness works for me. I will take a shot a patch-set
>>>> implementing this.
>>>
>>> Word "current" is not precise here.
>>>
>>> It can be thought of as either last brightness set by the
>>> user or the brightness currently written to the device
>>> (returned by brightness file).
>>>
>>> There is a semantic discrepancy in our requirements -
>>> we want the file representing both permanent brightness
>>> set by the user and brightness set by the hardware.
>>>
>>> The two stand in contradiction to each other since
>>> brightness set by the user can be adjusted by the hardware.
>>>
>>> Reading the file shouldn't update brightness property of
>>> struct led_classdev, so it shouldn't call led_update_brightness()
>>> but it still should allow reading brightness set by the
>>> hardware, as a result of each POLLPRI event. So in fact in
>>> the same time it should report both according to our requirements
>>> which is impossible. Do we need three brightness files ?
>>
>> I don't think so, current_brightness actually is an accurate
>> name, if the brightness was last changed by writing from
>> sysfs, the keyboard backlight will honor that and the current_brightness
>> attribute will show the brightness last set through writing it,
>> which matches the actual current brightness of the keyboard backlight.
>>
>> Likewise if it was changed with the hotkey last then the keyboard
>> backlight brightness will be changed and reading from current_brightness
>> will return the new actual brightness. Basically reading from this
>> file will be no different then reading from the normal "brightness"
>> file the difference will be in that it is poll-able and that
>> writing 0 turns off the LED without stopping blinking.
>
> If so then when software blinking enabled, it will return 0 on low
> blink cycle no matter what current brightness level is.

For software blinking there will not be a current_brightness atrribute,
as we will only add that for LEDs with poll-able triggers.

Also during the low cycle the LED is off, so its brightness at the
moment of reading (iow currently) is 0.

Regards,

Hans

^ permalink raw reply

* [GIT PULL] STM32 DT changes for v4.10 #2
From: Alexandre Torgue @ 2016-11-15 14:40 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Olof, Arnd and Kevin,

Please consider this second round of STM32 DT updates for v4.10:

The following changes since commit f6dbbff4f0af1a5c0d6eaf414572b5eff7a73a8b:

   ARM: dts: stm32f429: add LSI and LSE clocks (2016-11-04 15:08:08 +0100)

are available in the git repository at:

   git://git.kernel.org/pub/scm/linux/kernel/git/atorgue/stm32.git 
tags/stm32-dt-for-v4.10-2

for you to fetch changes up to 2ecaa477b404d707bac93c56f09a0a6162e04ed7:

   ARM: dts: stm32f429: Add QSPI clock (2016-11-15 13:59:11 +0100)

----------------------------------------------------------------
STM32 DT updates for v4.10, round 2.

Highlights:
----------
  - Add support of STM32F746 MCU and STM32746G-Eval board
  - Add QSPI support for STM32F469-Disco board

----------------------------------------------------------------
Alexandre TORGUE (1):
       ARM: dts: Add STM32F746 MCU and STM32746g-EVAL board

Gabriel Fernandez (1):
       ARM: dts: stm32f429: Add QSPI clock

  arch/arm/boot/dts/Makefile            |   3 +-
  arch/arm/boot/dts/stm32746g-eval.dts  |  96 +++++++++++
  arch/arm/boot/dts/stm32f469-disco.dts |   4 +
  arch/arm/boot/dts/stm32f746.dtsi      | 304 
++++++++++++++++++++++++++++++++++
  4 files changed, 406 insertions(+), 1 deletion(-)
  create mode 100644 arch/arm/boot/dts/stm32746g-eval.dts
  create mode 100644 arch/arm/boot/dts/stm32f746.dtsi

^ 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