Devicetree
 help / color / mirror / Atom feed
* Re: [PATCH 2/5] drivers: gpio: Add support for multiple IPs
From: Linus Walleij @ 2016-11-05  8:23 UTC (permalink / raw)
  To: Grygorii Strashko
  Cc: Keerthy, Roger Quadros, Alexandre Courbot, Lokesh Vutla,
	Rob Herring, linux-gpio-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Linux-OMAP
In-Reply-To: <b92f729b-5897-c29a-31ec-97510776d85d-l0cyMroinI0@public.gmane.org>

On Fri, Nov 4, 2016 at 8:59 PM, Grygorii Strashko
<grygorii.strashko-l0cyMroinI0@public.gmane.org> wrote:
> On 11/04/2016 09:28 AM, Linus Walleij wrote:

>> The DT model sort of mandates how the interrupts should be mapped
>> at this point, and as far as I can tell from the binding the example looks
>> like so:
>>
>> gpio: gpio@1e26000 {
>>         compatible = "ti,dm6441-gpio";
>>         gpio-controller;
>>         #gpio-cells = <2>;
>>         reg = <0x226000 0x1000>;
>>         interrupt-parent = <&intc>;
>>         interrupts = <42 IRQ_TYPE_EDGE_BOTH 43 IRQ_TYPE_EDGE_BOTH
>>                 44 IRQ_TYPE_EDGE_BOTH 45 IRQ_TYPE_EDGE_BOTH
>>                 46 IRQ_TYPE_EDGE_BOTH 47 IRQ_TYPE_EDGE_BOTH
>>                 48 IRQ_TYPE_EDGE_BOTH 49 IRQ_TYPE_EDGE_BOTH
>>                 50 IRQ_TYPE_EDGE_BOTH>;
>>         ti,ngpio = <144>;
>>         ti,davinci-gpio-unbanked = <0>;
>>         interrupt-controller;
>>         #interrupt-cells = <2>;
>> };
>
> Above, DT bindings models Davinci GPIO IP as monolithic GPIO controller
> with N gpio pins, but internally separate GPIO chips are created for each
> banksX&Y register set (32 pins, 2 banked irq -or- 32 direct irqs).

Hm it would be good to get away from that and just have one big gpio
chip.

> Translation from linear GPIO numbering to the proper internal GPIO chip is done
> using chip.of_xlate().

Yeah :/ this could be made simpler with a single chip just spanning all
the banks and the common registers I think.

Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v2 1/2] phy: rockchip-inno-usb2: support otg-port for rk3399
From: wlf @ 2016-11-05  2:58 UTC (permalink / raw)
  To: Kishon Vijay Abraham I, heiko-4mtYJXux2i+zQB+pC5nmwQ
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	frank.wang-TNX95d0MmH7DzftRWevZcw,
	huangtao-TNX95d0MmH7DzftRWevZcw, dianders-hpIqsD4AKlfQT0dZR+AlfA,
	briannorris-hpIqsD4AKlfQT0dZR+AlfA, groeck-hpIqsD4AKlfQT0dZR+AlfA
In-Reply-To: <0eeb3dd9-fc1e-f04b-4612-06367929ede6-l0cyMroinI0@public.gmane.org>

Hi Kishon,

在 2016年11月04日 01:17, Kishon Vijay Abraham I 写道:
>
> On Thursday 03 November 2016 07:36 AM, 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.
>>
>> Also, correct 480MHz output clock stable time. We found that
>> the system crashed due to 480MHz output clock of USB2 PHY was
>> unstable after clock had been enabled by gpu module.
> Can you split the clock fix into a separate patch?
OK, I will separate the clock patch in next version.

Best regards,
          wulf
>
> Thanks
> Kishon
>> Theoretically, 1 millisecond is a critical value for 480 output
>> clock stable time, so we try changing the delay time to 1.2
>> millisecond to avoid this issue.
>>
>> Signed-off-by: William Wu <wulf-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
>> ---
>> Changes in v2:
>> - remove wakelock
>>
>>   drivers/phy/phy-rockchip-inno-usb2.c | 593 +++++++++++++++++++++++++++++++++--
>>   1 file changed, 562 insertions(+), 31 deletions(-)
>>
>> diff --git a/drivers/phy/phy-rockchip-inno-usb2.c b/drivers/phy/phy-rockchip-inno-usb2.c
>> index ac20310..8f2d2b6 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];
>>   };
>> @@ -166,7 +267,7 @@ static int rockchip_usb2phy_clk480m_enable(struct clk_hw *hw)
>>   			return ret;
>>   
>>   		/* waitting for the clk become stable */
>> -		mdelay(1);
>> +		udelay(1200);
>>   	}
>>   
>>   	return 0;
>> @@ -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 },
>>
>
>


--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH v4 2/2] i2c: aspeed: added documentation for Aspeed I2C driver
From: Brendan Higgins @ 2016-11-05  1:58 UTC (permalink / raw)
  To: wsa, robh+dt, mark.rutland
  Cc: linux-i2c, devicetree, joel, openbmc, Brendan Higgins
In-Reply-To: <1478311099-6771-1-git-send-email-brendanhiggins@google.com>

Added device tree binding documentation for Aspeed I2C controller and
busses.

Signed-off-by: Brendan Higgins <brendanhiggins@google.com>
---
Changes for v2:
  - None
Changes for v3:
  - Removed reference to "bus" device tree param
Changes for v4:
  - None
---
 .../devicetree/bindings/i2c/i2c-aspeed.txt         | 61 ++++++++++++++++++++++
 1 file changed, 61 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/i2c/i2c-aspeed.txt

diff --git a/Documentation/devicetree/bindings/i2c/i2c-aspeed.txt b/Documentation/devicetree/bindings/i2c/i2c-aspeed.txt
new file mode 100644
index 0000000..dd11a97
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/i2c-aspeed.txt
@@ -0,0 +1,61 @@
+Device tree configuration for the I2C controller and busses on the AST24XX
+and AST25XX SoCs.
+
+Controller:
+
+	Required Properties:
+	- #address-cells	: should be 1
+	- #size-cells 		: should be 1
+	- #interrupt-cells 	: should be 1
+	- compatible 		: should be "aspeed,ast2400-i2c-controller"
+				  or "aspeed,ast2500-i2c-controller"
+	- reg			: address start and range of controller
+	- ranges		: defines address offset and range for busses
+	- interrupts		: interrupt number
+	- clocks		: root clock of bus, should reference the APB
+				  clock
+	- clock-ranges		: specifies that child busses can inherit clocks
+	- interrupt-controller	: denotes that the controller receives and fires
+				  new interrupts for child busses
+
+Bus:
+
+	Required Properties:
+	- #address-cells	: should be 1
+	- #size-cells		: should be 0
+	- reg			: address offset and range of bus
+	- compatible		: should be "aspeed,ast2400-i2c-bus"
+				  or "aspeed,ast2500-i2c-bus"
+	- interrupts		: interrupt number
+
+	Optional Properties:
+	- clock-frequency	: frequency of the bus clock in Hz
+				  defaults to 100 kHz when not specified
+
+Example:
+
+i2c: i2c@1e78a000 {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	#interrupt-cells = <1>;
+
+	compatible = "aspeed,ast2400-i2c-controller";
+	reg = <0x1e78a000 0x40>;
+	ranges = <0 0x1e78a000 0x1000>;
+	interrupts = <12>;
+	clocks = <&clk_apb>;
+	clock-ranges;
+	interrupt-controller;
+
+	i2c0: i2c-bus@40 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x40 0x40>;
+		compatible = "aspeed,ast2400-i2c-bus";
+		clock-frequency = <100000>;
+		status = "disabled";
+		interrupts = <0>;
+		interrupt-parent = <&i2c>;
+	};
+};
+
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related

* [PATCH v4 1/2] i2c: aspeed: added driver for Aspeed I2C
From: Brendan Higgins @ 2016-11-05  1:58 UTC (permalink / raw)
  To: wsa, robh+dt, mark.rutland
  Cc: linux-i2c, devicetree, joel, openbmc, Brendan Higgins
In-Reply-To: <1478311099-6771-1-git-send-email-brendanhiggins@google.com>

Added initial master and slave support for Aspeed I2C controller.
Supports fourteen busses present in ast24xx and ast25xx BMC SoCs by
Aspeed.

Signed-off-by: Brendan Higgins <brendanhiggins@google.com>
---
Changes for v2:
  - Added single module_init (multiple was breaking some builds).
Changes for v3:
  - Removed "bus" device tree param; now extracted from bus address offset
Changes for v4:
  - I2C adapter number is now generated dynamically unless specified in alias.
---
 drivers/i2c/busses/Kconfig      |  10 +
 drivers/i2c/busses/Makefile     |   1 +
 drivers/i2c/busses/i2c-aspeed.c | 807 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 818 insertions(+)
 create mode 100644 drivers/i2c/busses/i2c-aspeed.c

diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index d252276..b6caa5d 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -1009,6 +1009,16 @@ config I2C_RCAR
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-rcar.
 
+config I2C_ASPEED
+	tristate "Aspeed AST2xxx SoC I2C Controller"
+	depends on ARCH_ASPEED
+	help
+	  If you say yes to this option, support will be included for the
+	  Aspeed AST2xxx SoC I2C controller.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-aspeed.
+
 comment "External I2C/SMBus adapter drivers"
 
 config I2C_DIOLAN_U2C
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 29764cc..826e780 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -99,6 +99,7 @@ obj-$(CONFIG_I2C_XILINX)	+= i2c-xiic.o
 obj-$(CONFIG_I2C_XLR)		+= i2c-xlr.o
 obj-$(CONFIG_I2C_XLP9XX)	+= i2c-xlp9xx.o
 obj-$(CONFIG_I2C_RCAR)		+= i2c-rcar.o
+obj-$(CONFIG_I2C_ASPEED)	+= i2c-aspeed.o
 
 # External I2C/SMBus adapter drivers
 obj-$(CONFIG_I2C_DIOLAN_U2C)	+= i2c-diolan-u2c.o
diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c
new file mode 100644
index 0000000..88e078a
--- /dev/null
+++ b/drivers/i2c/busses/i2c-aspeed.c
@@ -0,0 +1,807 @@
+/*
+ *  I2C adapter for the ASPEED I2C bus.
+ *
+ *  Copyright (C) 2012-2020  ASPEED Technology Inc.
+ *  Copyright 2016 IBM Corporation
+ *  Copyright 2016 Google, Inc.
+ *
+ *  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/kernel.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/completion.h>
+#include <linux/slab.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+
+/* I2C Register */
+#define ASPEED_I2C_FUN_CTRL_REG				0x00
+#define ASPEED_I2C_AC_TIMING_REG1			0x04
+#define ASPEED_I2C_AC_TIMING_REG2			0x08
+#define ASPEED_I2C_INTR_CTRL_REG			0x0c
+#define ASPEED_I2C_INTR_STS_REG				0x10
+#define ASPEED_I2C_CMD_REG				0x14
+#define ASPEED_I2C_DEV_ADDR_REG				0x18
+#define ASPEED_I2C_BYTE_BUF_REG				0x20
+#define ASPEED_I2C_OFFSET_START				0x40
+#define ASPEED_I2C_OFFSET_INCREMENT			0x40
+
+#define ASPEED_I2C_NUM_BUS 14
+
+/* Global Register Definition */
+/* 0x00 : I2C Interrupt Status Register  */
+/* 0x08 : I2C Interrupt Target Assignment  */
+
+/* Device Register Definition */
+/* 0x00 : I2CD Function Control Register  */
+#define ASPEED_I2CD_MULTI_MASTER_DIS			BIT(15)
+#define ASPEED_I2CD_SDA_DRIVE_1T_EN			BIT(8)
+#define ASPEED_I2CD_M_SDA_DRIVE_1T_EN			BIT(7)
+#define ASPEED_I2CD_M_HIGH_SPEED_EN			BIT(6)
+#define ASPEED_I2CD_SLAVE_EN				BIT(1)
+#define ASPEED_I2CD_MASTER_EN				BIT(0)
+
+/* 0x08 : I2CD Clock and AC Timing Control Register #2 */
+#define ASPEED_NO_TIMEOUT_CTRL				0
+
+
+/* 0x0c : I2CD Interrupt Control Register &
+ * 0x10 : I2CD Interrupt Status Register
+ *
+ * These share bit definitions, so use the same values for the enable &
+ * status bits.
+ */
+#define ASPEED_I2CD_INTR_SDA_DL_TIMEOUT			BIT(14)
+#define ASPEED_I2CD_INTR_BUS_RECOVER_DONE		BIT(13)
+#define ASPEED_I2CD_INTR_SLAVE_MATCH			BIT(7)
+#define ASPEED_I2CD_INTR_SCL_TIMEOUT			BIT(6)
+#define ASPEED_I2CD_INTR_ABNORMAL			BIT(5)
+#define ASPEED_I2CD_INTR_NORMAL_STOP			BIT(4)
+#define ASPEED_I2CD_INTR_ARBIT_LOSS			BIT(3)
+#define ASPEED_I2CD_INTR_RX_DONE			BIT(2)
+#define ASPEED_I2CD_INTR_TX_NAK				BIT(1)
+#define ASPEED_I2CD_INTR_TX_ACK				BIT(0)
+
+/* 0x14 : I2CD Command/Status Register   */
+#define ASPEED_I2CD_SCL_LINE_STS			BIT(18)
+#define ASPEED_I2CD_SDA_LINE_STS			BIT(17)
+#define ASPEED_I2CD_BUS_BUSY_STS			BIT(16)
+#define ASPEED_I2CD_BUS_RECOVER_CMD			BIT(11)
+
+/* Command Bit */
+#define ASPEED_I2CD_M_STOP_CMD				BIT(5)
+#define ASPEED_I2CD_M_S_RX_CMD_LAST			BIT(4)
+#define ASPEED_I2CD_M_RX_CMD				BIT(3)
+#define ASPEED_I2CD_S_TX_CMD				BIT(2)
+#define ASPEED_I2CD_M_TX_CMD				BIT(1)
+#define ASPEED_I2CD_M_START_CMD				BIT(0)
+
+/* 0x18 : I2CD Slave Device Address Register   */
+#define ASPEED_I2CD_DEV_ADDR_MASK			GENMASK(6, 0)
+
+enum aspeed_i2c_slave_state {
+	ASPEED_I2C_SLAVE_START,
+	ASPEED_I2C_SLAVE_READ_REQUESTED,
+	ASPEED_I2C_SLAVE_READ_PROCESSED,
+	ASPEED_I2C_SLAVE_WRITE_REQUESTED,
+	ASPEED_I2C_SLAVE_WRITE_RECEIVED,
+	ASPEED_I2C_SLAVE_STOP,
+};
+
+struct aspeed_i2c_bus {
+	struct i2c_adapter		adap;
+	struct device			*dev;
+	void __iomem			*base;
+	spinlock_t			lock;
+	struct completion		cmd_complete;
+	int				irq;
+	/* Transaction state. */
+	struct i2c_msg			*msg;
+	int				msg_pos;
+	u32				cmd_err;
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+	struct i2c_client		*slave;
+	enum aspeed_i2c_slave_state	slave_state;
+#endif
+};
+
+struct aspeed_i2c_controller {
+	struct device		*dev;
+	void __iomem		*base;
+	int			irq;
+	struct irq_domain	*irq_domain;
+};
+
+static inline void aspeed_i2c_write(struct aspeed_i2c_bus *bus, u32 val,
+				    u32 reg)
+{
+	writel(val, bus->base + reg);
+}
+
+static inline u32 aspeed_i2c_read(struct aspeed_i2c_bus *bus, u32 reg)
+{
+	return readl(bus->base + reg);
+}
+
+static u8 aspeed_i2c_recover_bus(struct aspeed_i2c_bus *bus)
+{
+	u32 command;
+	unsigned long time_left;
+	unsigned long flags;
+	int ret = 0;
+
+	spin_lock_irqsave(&bus->lock, flags);
+	command = aspeed_i2c_read(bus, ASPEED_I2C_CMD_REG);
+	/* Bus is idle: no recovery needed. */
+	if ((command & ASPEED_I2CD_SDA_LINE_STS) &&
+	    (command & ASPEED_I2CD_SCL_LINE_STS))
+		goto out;
+
+	dev_dbg(bus->dev, "bus hung (state %x), attempting recovery\n",
+		command);
+
+	/* Bus held: put bus in stop state. */
+	if ((command & ASPEED_I2CD_SDA_LINE_STS) &&
+	    !(command & ASPEED_I2CD_SCL_LINE_STS)) {
+		aspeed_i2c_write(bus, ASPEED_I2CD_M_STOP_CMD,
+				 ASPEED_I2C_CMD_REG);
+		reinit_completion(&bus->cmd_complete);
+		spin_unlock_irqrestore(&bus->lock, flags);
+
+		time_left = wait_for_completion_interruptible_timeout(
+				&bus->cmd_complete, bus->adap.timeout * HZ);
+
+		spin_lock_irqsave(&bus->lock, flags);
+		if (time_left == 0)
+			ret = -ETIMEDOUT;
+		else if (bus->cmd_err)
+			ret = -EIO;
+	/* Bus error. */
+	} else if (!(command & ASPEED_I2CD_SDA_LINE_STS)) {
+		aspeed_i2c_write(bus, ASPEED_I2CD_BUS_RECOVER_CMD,
+				 ASPEED_I2C_CMD_REG);
+		reinit_completion(&bus->cmd_complete);
+		spin_unlock_irqrestore(&bus->lock, flags);
+
+		time_left = wait_for_completion_interruptible_timeout(
+				&bus->cmd_complete, bus->adap.timeout * HZ);
+
+		spin_lock_irqsave(&bus->lock, flags);
+		if (time_left == 0)
+			ret = -ETIMEDOUT;
+		else if (bus->cmd_err)
+			ret = -EIO;
+		/* Recovery failed. */
+		else if (!(aspeed_i2c_read(bus, ASPEED_I2C_CMD_REG) &
+			   ASPEED_I2CD_SDA_LINE_STS))
+			ret = -EIO;
+	}
+
+out:
+	spin_unlock_irqrestore(&bus->lock, flags);
+	return ret;
+}
+
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+static bool aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus)
+{
+	bool irq_handled = true;
+	u32 command;
+	u32 irq_status;
+	u32 status_ack = 0;
+	u8 value;
+	struct i2c_client *slave = bus->slave;
+
+	spin_lock(&bus->lock);
+	if (!slave) {
+		irq_handled = false;
+		goto out;
+	}
+	command = aspeed_i2c_read(bus, ASPEED_I2C_CMD_REG);
+	irq_status = aspeed_i2c_read(bus, ASPEED_I2C_INTR_STS_REG);
+
+	/* Slave was requested, restart state machine. */
+	if (irq_status & ASPEED_I2CD_INTR_SLAVE_MATCH) {
+		status_ack |= ASPEED_I2CD_INTR_SLAVE_MATCH;
+		bus->slave_state = ASPEED_I2C_SLAVE_START;
+	}
+	/* Slave is not currently active, irq was for someone else. */
+	if (bus->slave_state == ASPEED_I2C_SLAVE_STOP) {
+		irq_handled = false;
+		goto out;
+	}
+
+	dev_dbg(bus->dev, "slave irq status 0x%08x, cmd 0x%08x\n",
+		irq_status, command);
+
+	/* Slave was sent something. */
+	if (irq_status & ASPEED_I2CD_INTR_RX_DONE) {
+		value = aspeed_i2c_read(bus, ASPEED_I2C_BYTE_BUF_REG) >> 8;
+		/* Handle address frame. */
+		if (bus->slave_state == ASPEED_I2C_SLAVE_START) {
+			if (value & 0x1)
+				bus->slave_state =
+						ASPEED_I2C_SLAVE_READ_REQUESTED;
+			else
+				bus->slave_state =
+						ASPEED_I2C_SLAVE_WRITE_REQUESTED;
+		}
+		status_ack |= ASPEED_I2CD_INTR_RX_DONE;
+	}
+
+	/* Slave was asked to stop. */
+	if (irq_status & ASPEED_I2CD_INTR_NORMAL_STOP) {
+		status_ack |= ASPEED_I2CD_INTR_NORMAL_STOP;
+		bus->slave_state = ASPEED_I2C_SLAVE_STOP;
+	}
+	if (irq_status & ASPEED_I2CD_INTR_TX_NAK) {
+		status_ack |= ASPEED_I2CD_INTR_TX_NAK;
+		bus->slave_state = ASPEED_I2C_SLAVE_STOP;
+	}
+
+	if (bus->slave_state == ASPEED_I2C_SLAVE_READ_REQUESTED) {
+		if (irq_status & ASPEED_I2CD_INTR_TX_ACK)
+			dev_err(bus->dev, "Unexpected ACK on read request.\n");
+		bus->slave_state = ASPEED_I2C_SLAVE_READ_PROCESSED;
+
+		i2c_slave_event(slave, I2C_SLAVE_READ_REQUESTED, &value);
+		aspeed_i2c_write(bus, value, ASPEED_I2C_BYTE_BUF_REG);
+		aspeed_i2c_write(bus, ASPEED_I2CD_S_TX_CMD, ASPEED_I2C_CMD_REG);
+	} else if (bus->slave_state == ASPEED_I2C_SLAVE_READ_PROCESSED) {
+		status_ack |= ASPEED_I2CD_INTR_TX_ACK;
+		if (!(irq_status & ASPEED_I2CD_INTR_TX_ACK))
+			dev_err(bus->dev,
+				"Expected ACK after processed read.\n");
+		i2c_slave_event(slave, I2C_SLAVE_READ_PROCESSED, &value);
+		aspeed_i2c_write(bus, value, ASPEED_I2C_BYTE_BUF_REG);
+		aspeed_i2c_write(bus, ASPEED_I2CD_S_TX_CMD, ASPEED_I2C_CMD_REG);
+	} else if (bus->slave_state == ASPEED_I2C_SLAVE_WRITE_REQUESTED) {
+		bus->slave_state = ASPEED_I2C_SLAVE_WRITE_RECEIVED;
+		i2c_slave_event(slave, I2C_SLAVE_WRITE_REQUESTED, &value);
+	} else if (bus->slave_state == ASPEED_I2C_SLAVE_WRITE_RECEIVED) {
+		i2c_slave_event(slave, I2C_SLAVE_WRITE_RECEIVED, &value);
+	} else if (bus->slave_state == ASPEED_I2C_SLAVE_STOP) {
+		i2c_slave_event(slave, I2C_SLAVE_STOP, &value);
+	}
+
+	if (status_ack != irq_status)
+		dev_err(bus->dev,
+			"irq handled != irq. expected %x, but was %x\n",
+			irq_status, status_ack);
+	aspeed_i2c_write(bus, status_ack, ASPEED_I2C_INTR_STS_REG);
+
+out:
+	spin_unlock(&bus->lock);
+	return irq_handled;
+}
+#endif
+
+static bool aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus)
+{
+	const u32 errs = ASPEED_I2CD_INTR_ARBIT_LOSS |
+		ASPEED_I2CD_INTR_ABNORMAL |
+		ASPEED_I2CD_INTR_SCL_TIMEOUT |
+		ASPEED_I2CD_INTR_SDA_DL_TIMEOUT |
+		ASPEED_I2CD_INTR_TX_NAK;
+	u32 irq_status;
+
+	spin_lock(&bus->lock);
+	irq_status = aspeed_i2c_read(bus, ASPEED_I2C_INTR_STS_REG);
+	bus->cmd_err = irq_status & errs;
+
+	dev_dbg(bus->dev, "master irq status 0x%08x\n", irq_status);
+
+	/* No message to transfer. */
+	if (bus->cmd_err ||
+	    (irq_status & ASPEED_I2CD_INTR_NORMAL_STOP) ||
+	    (irq_status & ASPEED_I2CD_INTR_BUS_RECOVER_DONE)) {
+		complete(&bus->cmd_complete);
+		goto out;
+	} else if (!bus->msg || bus->msg_pos >= bus->msg->len)
+		goto out;
+
+	if ((bus->msg->flags & I2C_M_RD) &&
+	    (irq_status & ASPEED_I2CD_INTR_RX_DONE)) {
+		bus->msg->buf[bus->msg_pos++] = aspeed_i2c_read(
+				bus, ASPEED_I2C_BYTE_BUF_REG) >> 8;
+		if (bus->msg_pos + 1 < bus->msg->len)
+			aspeed_i2c_write(bus, ASPEED_I2CD_M_RX_CMD,
+					 ASPEED_I2C_CMD_REG);
+		else if (bus->msg_pos < bus->msg->len)
+			aspeed_i2c_write(bus, ASPEED_I2CD_M_RX_CMD |
+				      ASPEED_I2CD_M_S_RX_CMD_LAST,
+				      ASPEED_I2C_CMD_REG);
+	} else if (!(bus->msg->flags & I2C_M_RD) &&
+		   (irq_status & ASPEED_I2CD_INTR_TX_ACK)) {
+		aspeed_i2c_write(bus, bus->msg->buf[bus->msg_pos++],
+			      ASPEED_I2C_BYTE_BUF_REG);
+		aspeed_i2c_write(bus, ASPEED_I2CD_M_TX_CMD, ASPEED_I2C_CMD_REG);
+	}
+
+	/* Transmission complete: notify caller. */
+	if (bus->msg_pos >= bus->msg->len)
+		complete(&bus->cmd_complete);
+out:
+	aspeed_i2c_write(bus, irq_status, ASPEED_I2C_INTR_STS_REG);
+	spin_unlock(&bus->lock);
+	return true;
+}
+
+static irqreturn_t aspeed_i2c_bus_irq(int irq, void *dev_id)
+{
+	struct aspeed_i2c_bus *bus = dev_id;
+
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+	if (aspeed_i2c_slave_irq(bus)) {
+		dev_dbg(bus->dev, "irq handled by slave.\n");
+		return IRQ_HANDLED;
+	}
+#endif
+	if (aspeed_i2c_master_irq(bus)) {
+		dev_dbg(bus->dev, "irq handled by master.\n");
+		return IRQ_HANDLED;
+	}
+	dev_err(bus->dev, "irq not handled properly!\n");
+	return IRQ_HANDLED;
+}
+
+static int aspeed_i2c_master_single_xfer(struct i2c_adapter *adap,
+				      struct i2c_msg *msg)
+{
+	struct aspeed_i2c_bus *bus = adap->algo_data;
+	unsigned long flags;
+	u8 slave_addr;
+	u32 command = ASPEED_I2CD_M_START_CMD | ASPEED_I2CD_M_TX_CMD;
+	int ret = msg->len;
+	unsigned long time_left;
+
+	spin_lock_irqsave(&bus->lock, flags);
+	bus->msg = msg;
+	bus->msg_pos = 0;
+	slave_addr = msg->addr << 1;
+	if (msg->flags & I2C_M_RD) {
+		slave_addr |= 1;
+		command |= ASPEED_I2CD_M_RX_CMD;
+		if (msg->len == 1)
+			command |= ASPEED_I2CD_M_S_RX_CMD_LAST;
+	}
+	aspeed_i2c_write(bus, slave_addr, ASPEED_I2C_BYTE_BUF_REG);
+	aspeed_i2c_write(bus, command, ASPEED_I2C_CMD_REG);
+	reinit_completion(&bus->cmd_complete);
+	spin_unlock_irqrestore(&bus->lock, flags);
+
+	time_left = wait_for_completion_interruptible_timeout(
+			&bus->cmd_complete, bus->adap.timeout * HZ * msg->len);
+	if (time_left == 0)
+		return -ETIMEDOUT;
+
+	spin_lock_irqsave(&bus->lock, flags);
+	if (bus->cmd_err)
+		ret = -EIO;
+	bus->msg = NULL;
+	spin_unlock_irqrestore(&bus->lock, flags);
+
+	return ret;
+}
+
+static int aspeed_i2c_master_xfer(struct i2c_adapter *adap,
+				  struct i2c_msg *msgs, int num)
+{
+	struct aspeed_i2c_bus *bus = adap->algo_data;
+	int ret;
+	int i;
+	unsigned long flags;
+	unsigned long time_left;
+
+	/* If bus is busy, attempt recovery. We assume a single master
+	 * environment.
+	 */
+	if (aspeed_i2c_read(bus, ASPEED_I2C_CMD_REG) &
+	    ASPEED_I2CD_BUS_BUSY_STS) {
+		ret = aspeed_i2c_recover_bus(bus);
+		if (ret)
+			return ret;
+	}
+
+	for (i = 0; i < num; i++) {
+		ret = aspeed_i2c_master_single_xfer(adap, &msgs[i]);
+		if (ret < 0)
+			break;
+		/* TODO: Support other forms of I2C protocol mangling. */
+		if (msgs[i].flags & I2C_M_STOP) {
+			spin_lock_irqsave(&bus->lock, flags);
+			aspeed_i2c_write(bus, ASPEED_I2CD_M_STOP_CMD,
+				      ASPEED_I2C_CMD_REG);
+			reinit_completion(&bus->cmd_complete);
+			spin_unlock_irqrestore(&bus->lock, flags);
+
+			time_left = wait_for_completion_interruptible_timeout(
+					&bus->cmd_complete,
+					bus->adap.timeout * HZ);
+			if (time_left == 0)
+				return -ETIMEDOUT;
+		}
+	}
+
+	spin_lock_irqsave(&bus->lock, flags);
+	aspeed_i2c_write(bus, ASPEED_I2CD_M_STOP_CMD, ASPEED_I2C_CMD_REG);
+	reinit_completion(&bus->cmd_complete);
+	spin_unlock_irqrestore(&bus->lock, flags);
+
+	time_left = wait_for_completion_interruptible_timeout(
+			&bus->cmd_complete, bus->adap.timeout * HZ);
+	if (time_left == 0)
+		return -ETIMEDOUT;
+
+	/* If nothing went wrong, return number of messages transferred. */
+	if (ret < 0)
+		return ret;
+	else
+		return i;
+}
+
+static u32 aspeed_i2c_functionality(struct i2c_adapter *adap)
+{
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_SMBUS_BLOCK_DATA;
+}
+
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+static int aspeed_i2c_reg_slave(struct i2c_client *client)
+{
+	struct aspeed_i2c_bus *bus;
+	unsigned long flags;
+	u32 addr_reg_val;
+	u32 func_ctrl_reg_val;
+
+	bus = client->adapter->algo_data;
+	spin_lock_irqsave(&bus->lock, flags);
+	if (bus->slave) {
+		spin_unlock_irqrestore(&bus->lock, flags);
+		return -EINVAL;
+	}
+
+	/* Set slave addr. */
+	addr_reg_val = aspeed_i2c_read(bus, ASPEED_I2C_DEV_ADDR_REG);
+	addr_reg_val &= ~ASPEED_I2CD_DEV_ADDR_MASK;
+	addr_reg_val |= client->addr & ASPEED_I2CD_DEV_ADDR_MASK;
+	aspeed_i2c_write(bus, addr_reg_val, ASPEED_I2C_DEV_ADDR_REG);
+
+	/* Switch from master mode to slave mode. */
+	func_ctrl_reg_val = aspeed_i2c_read(bus, ASPEED_I2C_FUN_CTRL_REG);
+	func_ctrl_reg_val &= ~ASPEED_I2CD_MASTER_EN;
+	func_ctrl_reg_val |= ASPEED_I2CD_SLAVE_EN;
+	aspeed_i2c_write(bus, func_ctrl_reg_val, ASPEED_I2C_FUN_CTRL_REG);
+
+	bus->slave = client;
+	bus->slave_state = ASPEED_I2C_SLAVE_STOP;
+	spin_unlock_irqrestore(&bus->lock, flags);
+	return 0;
+}
+
+static int aspeed_i2c_unreg_slave(struct i2c_client *client)
+{
+	struct aspeed_i2c_bus *bus = client->adapter->algo_data;
+	unsigned long flags;
+	u32 func_ctrl_reg_val;
+
+	spin_lock_irqsave(&bus->lock, flags);
+	if (!bus->slave) {
+		spin_unlock_irqrestore(&bus->lock, flags);
+		return -EINVAL;
+	}
+
+	/* Switch from slave mode to master mode. */
+	func_ctrl_reg_val = aspeed_i2c_read(bus, ASPEED_I2C_FUN_CTRL_REG);
+	func_ctrl_reg_val &= ~ASPEED_I2CD_SLAVE_EN;
+	func_ctrl_reg_val |= ASPEED_I2CD_MASTER_EN;
+	aspeed_i2c_write(bus, func_ctrl_reg_val, ASPEED_I2C_FUN_CTRL_REG);
+
+	bus->slave = NULL;
+	spin_unlock_irqrestore(&bus->lock, flags);
+	return 0;
+}
+#endif
+
+static const struct i2c_algorithm aspeed_i2c_algo = {
+	.master_xfer	= aspeed_i2c_master_xfer,
+	.functionality	= aspeed_i2c_functionality,
+#if IS_ENABLED(CONFIG_I2C_SLAVE)
+	.reg_slave	= aspeed_i2c_reg_slave,
+	.unreg_slave	= aspeed_i2c_unreg_slave,
+#endif
+};
+
+static u32 aspeed_i2c_get_clk_reg_val(u32 divider_ratio)
+{
+	unsigned int inc = 0, div;
+	u32 scl_low, scl_high, data;
+
+	for (div = 0; divider_ratio >= 16; div++) {
+		inc |= (divider_ratio & 1);
+		divider_ratio >>= 1;
+	}
+	divider_ratio += inc;
+	scl_low = (divider_ratio >> 1) - 1;
+	scl_high = divider_ratio - scl_low - 2;
+	data = 0x77700300 | (scl_high << 16) | (scl_low << 12) | div;
+	return data;
+}
+
+static int aspeed_i2c_init_clk(struct aspeed_i2c_bus *bus,
+			    struct platform_device *pdev)
+{
+	struct clk *pclk;
+	u32 clk_freq;
+	u32 divider_ratio;
+	int ret;
+
+	pclk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(pclk)) {
+		dev_err(&pdev->dev, "clk_get failed\n");
+		return PTR_ERR(pclk);
+	}
+	ret = of_property_read_u32(pdev->dev.of_node,
+			"clock-frequency", &clk_freq);
+	if (ret < 0) {
+		dev_err(&pdev->dev,
+				"Could not read clock-frequency property\n");
+		clk_freq = 100000;
+	}
+	divider_ratio = clk_get_rate(pclk) / clk_freq;
+	/* We just need the clock rate, we don't actually use the clk object. */
+	devm_clk_put(&pdev->dev, pclk);
+
+	/* Set AC Timing */
+	if (clk_freq / 1000 > 400) {
+		aspeed_i2c_write(bus, aspeed_i2c_read(bus,
+						      ASPEED_I2C_FUN_CTRL_REG) |
+				ASPEED_I2CD_M_HIGH_SPEED_EN |
+				ASPEED_I2CD_M_SDA_DRIVE_1T_EN |
+				ASPEED_I2CD_SDA_DRIVE_1T_EN,
+				ASPEED_I2C_FUN_CTRL_REG);
+
+		aspeed_i2c_write(bus, 0x3, ASPEED_I2C_AC_TIMING_REG2);
+		aspeed_i2c_write(bus, aspeed_i2c_get_clk_reg_val(divider_ratio),
+			      ASPEED_I2C_AC_TIMING_REG1);
+	} else {
+		aspeed_i2c_write(bus, aspeed_i2c_get_clk_reg_val(divider_ratio),
+			      ASPEED_I2C_AC_TIMING_REG1);
+		aspeed_i2c_write(bus, ASPEED_NO_TIMEOUT_CTRL,
+				 ASPEED_I2C_AC_TIMING_REG2);
+	}
+
+	return 0;
+}
+
+static void noop(struct irq_data *data) { }
+
+static struct irq_chip aspeed_i2c_irqchip = {
+	.name		= "ast-i2c",
+	.irq_unmask	= noop,
+	.irq_mask	= noop,
+};
+
+static int aspeed_i2c_probe_bus(struct platform_device *pdev)
+{
+	struct aspeed_i2c_bus *bus;
+	struct aspeed_i2c_controller *controller =
+			dev_get_drvdata(pdev->dev.parent);
+	struct resource *res;
+	int ret, irq;
+	u32 hwirq;
+
+	bus = devm_kzalloc(&pdev->dev, sizeof(*bus), GFP_KERNEL);
+	if (!bus)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	bus->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(bus->base))
+		return PTR_ERR(bus->base);
+
+	bus->irq = platform_get_irq(pdev, 0);
+	if (bus->irq < 0)
+		return -ENXIO;
+	ret = of_property_read_u32(pdev->dev.of_node, "interrupts", &hwirq);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "no I2C 'interrupts' property\n");
+		return -ENXIO;
+	}
+	irq = irq_create_mapping(controller->irq_domain, hwirq);
+	irq_set_chip_data(irq, controller);
+	irq_set_chip_and_handler(irq, &aspeed_i2c_irqchip, handle_simple_irq);
+	ret = devm_request_irq(&pdev->dev, bus->irq, aspeed_i2c_bus_irq,
+			0, dev_name(&pdev->dev), bus);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to request interrupt\n");
+		return -ENXIO;
+	}
+
+	/* Initialize the I2C adapter */
+	spin_lock_init(&bus->lock);
+	init_completion(&bus->cmd_complete);
+	bus->adap.owner = THIS_MODULE;
+	bus->adap.retries = 0;
+	bus->adap.timeout = 5;
+	bus->adap.algo = &aspeed_i2c_algo;
+	bus->adap.algo_data = bus;
+	bus->adap.dev.parent = &pdev->dev;
+	bus->adap.dev.of_node = pdev->dev.of_node;
+	snprintf(bus->adap.name, sizeof(bus->adap.name), "Aspeed i2c");
+
+	bus->dev = &pdev->dev;
+
+	/* reset device: disable master & slave functions */
+	aspeed_i2c_write(bus, 0, ASPEED_I2C_FUN_CTRL_REG);
+
+	ret = aspeed_i2c_init_clk(bus, pdev);
+	if (ret < 0)
+		return ret;
+
+	/* Enable Master Mode */
+	aspeed_i2c_write(bus, aspeed_i2c_read(bus, ASPEED_I2C_FUN_CTRL_REG) |
+		      ASPEED_I2CD_MASTER_EN |
+		      ASPEED_I2CD_MULTI_MASTER_DIS, ASPEED_I2C_FUN_CTRL_REG);
+
+	/* Set interrupt generation of I2C controller */
+	aspeed_i2c_write(bus, ASPEED_I2CD_INTR_SDA_DL_TIMEOUT |
+			ASPEED_I2CD_INTR_BUS_RECOVER_DONE |
+			ASPEED_I2CD_INTR_SCL_TIMEOUT |
+			ASPEED_I2CD_INTR_ABNORMAL |
+			ASPEED_I2CD_INTR_NORMAL_STOP |
+			ASPEED_I2CD_INTR_ARBIT_LOSS |
+			ASPEED_I2CD_INTR_RX_DONE |
+			ASPEED_I2CD_INTR_TX_NAK |
+			ASPEED_I2CD_INTR_TX_ACK,
+			ASPEED_I2C_INTR_CTRL_REG);
+
+	ret = i2c_add_adapter(&bus->adap);
+	if (ret < 0)
+		return -ENXIO;
+
+	platform_set_drvdata(pdev, bus);
+
+	dev_info(bus->dev, "i2c bus %d registered, irq %d\n",
+			bus->adap.nr, bus->irq);
+
+	return 0;
+}
+
+static int aspeed_i2c_remove_bus(struct platform_device *pdev)
+{
+	struct aspeed_i2c_bus *bus = platform_get_drvdata(pdev);
+
+	i2c_del_adapter(&bus->adap);
+	return 0;
+}
+
+static const struct of_device_id aspeed_i2c_bus_of_table[] = {
+	{ .compatible = "aspeed,ast2400-i2c-bus", },
+	{ .compatible = "aspeed,ast2500-i2c-bus", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, aspeed_i2c_bus_of_table);
+
+static struct platform_driver aspeed_i2c_bus_driver = {
+	.probe		= aspeed_i2c_probe_bus,
+	.remove		= aspeed_i2c_remove_bus,
+	.driver		= {
+		.name		= "ast-i2c-bus",
+		.of_match_table	= aspeed_i2c_bus_of_table,
+	},
+};
+
+static void aspeed_i2c_controller_irq(struct irq_desc *desc)
+{
+	struct aspeed_i2c_controller *c = irq_desc_get_handler_data(desc);
+	unsigned long p, status;
+	unsigned int bus_irq;
+
+	status = readl(c->base);
+	for_each_set_bit(p, &status, ASPEED_I2C_NUM_BUS) {
+		bus_irq = irq_find_mapping(c->irq_domain, p);
+		generic_handle_irq(bus_irq);
+	}
+}
+
+static int aspeed_i2c_probe_controller(struct platform_device *pdev)
+{
+	struct aspeed_i2c_controller *controller;
+	struct device_node *np;
+	struct resource *res;
+
+	controller = kzalloc(sizeof(*controller), GFP_KERNEL);
+	if (!controller)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	controller->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(controller->base))
+		return PTR_ERR(controller->base);
+
+	controller->irq = platform_get_irq(pdev, 0);
+	if (controller->irq < 0)
+		return -ENXIO;
+
+	controller->irq_domain = irq_domain_add_linear(pdev->dev.of_node,
+			ASPEED_I2C_NUM_BUS, &irq_domain_simple_ops, NULL);
+	if (!controller->irq_domain)
+		return -ENXIO;
+	controller->irq_domain->name = "ast-i2c-domain";
+
+	irq_set_chained_handler_and_data(controller->irq,
+			aspeed_i2c_controller_irq, controller);
+
+	controller->dev = &pdev->dev;
+
+	platform_set_drvdata(pdev, controller);
+
+	dev_info(controller->dev, "i2c controller registered, irq %d\n",
+			controller->irq);
+
+	for_each_child_of_node(pdev->dev.of_node, np) {
+		of_platform_device_create(np, NULL, &pdev->dev);
+		of_node_put(np);
+	}
+
+	return 0;
+}
+
+static int aspeed_i2c_remove_controller(struct platform_device *pdev)
+{
+	struct aspeed_i2c_controller *controller = platform_get_drvdata(pdev);
+
+	irq_domain_remove(controller->irq_domain);
+	return 0;
+}
+
+static const struct of_device_id aspeed_i2c_controller_of_table[] = {
+	{ .compatible = "aspeed,ast2400-i2c-controller", },
+	{ .compatible = "aspeed,ast2500-i2c-controller", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, aspeed_i2c_controller_of_table);
+
+static struct platform_driver aspeed_i2c_controller_driver = {
+	.probe		= aspeed_i2c_probe_controller,
+	.remove		= aspeed_i2c_remove_controller,
+	.driver		= {
+		.name		= "ast-i2c-controller",
+		.of_match_table	= aspeed_i2c_controller_of_table,
+	},
+};
+
+static int __init aspeed_i2c_driver_init(void)
+{
+	int ret;
+
+	ret = platform_driver_register(&aspeed_i2c_controller_driver);
+	if (ret < 0)
+		return ret;
+	return platform_driver_register(&aspeed_i2c_bus_driver);
+}
+module_init(aspeed_i2c_driver_init);
+
+static void __exit aspeed_i2c_driver_exit(void)
+{
+	platform_driver_unregister(&aspeed_i2c_bus_driver);
+	platform_driver_unregister(&aspeed_i2c_controller_driver);
+}
+module_exit(aspeed_i2c_driver_exit);
+
+MODULE_AUTHOR("Brendan Higgins <brendanhiggins@google.com>");
+MODULE_DESCRIPTION("Aspeed I2C Bus Driver");
+MODULE_LICENSE("GPL");
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related

* [PATCH v4 0/2] i2c: aspeed: added driver for Aspeed I2C
From: Brendan Higgins @ 2016-11-05  1:58 UTC (permalink / raw)
  To: wsa-z923LK4zBo2bacvFa/9K2g, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	mark.rutland-5wv7dgnIgG8
  Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, joel-U3u1mxZcP9KHXe+LvDLADg,
	openbmc-uLR06cmDAlY/bJ5BZ2RsiQ

Sorry, been a while since I was able to send an update for this.

As a refresher, I added a master mode and slave mode I2C driver for the Aspeed
24XX/25XX SoC as well as device binding documentation.

Changes since first update:
  - I have removed the bus device tree param as requested here:
    http://www.spinics.net/lists/devicetree/msg143850.html
  - I2C adapter number is now generated dynamically unless an alias is provided
  - I changed the Kconfig for the driver to depend only on ARCH_ASPEED
  - Replaced the two module_platform_driver registrations with single
    module_init

Changes have been tested on the Aspeed evaluation board.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v2 1/3] remoteproc: qcom: Encapsulate pvt data structure for q6v56 hexagon.
From: kbuild test robot @ 2016-11-04 23:51 UTC (permalink / raw)
  Cc: kbuild-all-JC7UmRfGjtg, bjorn.andersson-QSEj5FYQhm4dnm+yROfE0A,
	Avaneesh Kumar Dwivedi, Ohad Ben-Cohen, Rob Herring, Mark Rutland,
	open list:REMOTE PROCESSOR (REMOTEPROC) SUBSYSTEM,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list
In-Reply-To: <1478268057-11847-2-git-send-email-akdwived-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 7190 bytes --]

Hi Avaneesh,

[auto build test ERROR on robh/for-next]
[also build test ERROR on v4.9-rc3 next-20161028]
[cannot apply to remoteproc/for-next]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
[Suggest to use git(>=2.9.0) format-patch --base=<commit> (or --base=auto for convenience) to record what (public, well-known) commit your patch series was built on]
[Check https://git-scm.com/docs/git-format-patch for more information]

url:    https://github.com/0day-ci/linux/commits/Avaneesh-Kumar-Dwivedi/remoteproc-qcom-Encapsulate-pvt-data-structure-for-q6v56-hexagon/20161104-220712
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
config: arm64-allyesconfig (attached as .config)
compiler: aarch64-linux-gnu-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=arm64 

Note: the linux-review/Avaneesh-Kumar-Dwivedi/remoteproc-qcom-Encapsulate-pvt-data-structure-for-q6v56-hexagon/20161104-220712 HEAD 1b4c0b8bb3bb8cd30a996282b7a6aa9f352836a2 builds fine.
      It only hurts bisectibility.

All errors (new ones prefixed by >>):

   drivers/remoteproc/qcom_q6v5_pil.c: In function 'q6_probe':
   drivers/remoteproc/qcom_q6v5_pil.c:848:7: warning: assignment discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
     desc = of_device_get_match_data(&pdev->dev);
          ^
   drivers/remoteproc/qcom_q6v5_pil.c: At top level:
>> drivers/remoteproc/qcom_q6v5_pil.c:986:19: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
     .q6_reset_init = q6v5_init_reset,
                      ^~~~~~~~~~~~~~~
   drivers/remoteproc/qcom_q6v5_pil.c:986:19: note: (near initialization for 'msm_8916_res.q6_reset_init')
   cc1: some warnings being treated as errors

vim +986 drivers/remoteproc/qcom_q6v5_pil.c

   842	{
   843		struct q6v5 *qproc;
   844		struct rproc *rproc;
   845		struct q6_rproc_res *desc;
   846		int ret;
   847	
 > 848		desc = of_device_get_match_data(&pdev->dev);
   849		if (!desc)
   850			return -EINVAL;
   851	
   852		rproc = rproc_alloc(&pdev->dev, pdev->name, &q6_ops,
   853				    desc->q6_mba_image, sizeof(*qproc));
   854		if (!rproc) {
   855			dev_err(&pdev->dev, "failed to allocate rproc\n");
   856			return -ENOMEM;
   857		}
   858	
   859		rproc->fw_ops = &q6_fw_ops;
   860	
   861		qproc = (struct q6v5 *)rproc->priv;
   862		qproc->dev = &pdev->dev;
   863		qproc->rproc = rproc;
   864		platform_set_drvdata(pdev, qproc);
   865	
   866		init_completion(&qproc->start_done);
   867		init_completion(&qproc->stop_done);
   868	
   869		qproc->q6_rproc_res = desc;
   870		ret = q6v5_init_mem(qproc, pdev);
   871		if (ret)
   872			goto free_rproc;
   873	
   874		ret = q6v5_alloc_memory_region(qproc);
   875		if (ret)
   876			goto free_rproc;
   877	
   878		ret = q6v5_init_clocks(qproc);
   879		if (ret)
   880			goto free_rproc;
   881	
   882		ret = q6v5_regulator_init(qproc);
   883		if (ret)
   884			goto free_rproc;
   885	
   886		ret = qproc->q6_rproc_res->q6_reset_init(qproc, pdev);
   887		if (ret)
   888			goto free_rproc;
   889	
   890		ret = q6v5_request_irq(qproc, pdev, "wdog", q6v5_wdog_interrupt);
   891		if (ret < 0)
   892			goto free_rproc;
   893	
   894		ret = q6v5_request_irq(qproc, pdev, "fatal", q6v5_fatal_interrupt);
   895		if (ret < 0)
   896			goto free_rproc;
   897	
   898		ret = q6v5_request_irq(qproc, pdev, "handover", q6v5_handover_interrupt);
   899		if (ret < 0)
   900			goto free_rproc;
   901	
   902		ret = q6v5_request_irq(qproc, pdev, "stop-ack", q6v5_stop_ack_interrupt);
   903		if (ret < 0)
   904			goto free_rproc;
   905	
   906		qproc->state = qcom_smem_state_get(&pdev->dev, "stop", &qproc->stop_bit);
   907		if (IS_ERR(qproc->state))
   908			goto free_rproc;
   909	
   910		ret = rproc_add(rproc);
   911		if (ret)
   912			goto free_rproc;
   913	
   914		return 0;
   915	
   916	free_rproc:
   917		rproc_put(rproc);
   918	
   919		return ret;
   920	}
   921	
   922	static int q6_remove(struct platform_device *pdev)
   923	{
   924		struct q6v5 *qproc = platform_get_drvdata(pdev);
   925	
   926		rproc_del(qproc->rproc);
   927		rproc_put(qproc->rproc);
   928	
   929		return 0;
   930	}
   931	
   932	char *proxy_8x96_reg_str[] = {"mx", "cx", "vdd_pll"};
   933	int  proxy_8x96_reg_action[3][2] = { {0, 1}, {1, 1}, {1, 0} };
   934	int  proxy_8x96_reg_load[] = {0, 100000, 100000};
   935	int  proxy_8x96_reg_min_voltage[] = {1050000, 1250000, 0};
   936	char *proxy_8x96_clk_str[] = {"xo", "pnoc", "qdss"};
   937	char *active_8x96_clk_str[] = {"iface", "bus", "mem", "gpll0_mss_clk",
   938			"snoc_axi_clk", "mnoc_axi_clk"};
   939	
   940	static struct q6_rproc_res msm_8996_res = {
   941		.proxy_clks = proxy_8x96_clk_str,
   942		.proxy_clk_cnt = 3,
   943		.active_clks = active_8x96_clk_str,
   944		.active_clk_cnt = 6,
   945		.proxy_regs = proxy_8x96_reg_str,
   946		.active_regs = NULL,
   947		.proxy_reg_action = (int **)proxy_8x96_reg_action,
   948		.proxy_reg_load = (int *)proxy_8x96_reg_load,
   949		.active_reg_action = NULL,
   950		.active_reg_load = NULL,
   951		.proxy_reg_voltage = (int *)proxy_8x96_reg_min_voltage,
   952		.active_reg_voltage = NULL,
   953		.proxy_reg_cnt = 3,
   954		.active_reg_cnt = 0,
   955		.q6_reset_init = q6v56_init_reset,
   956		.q6_version = "v56",
   957		.q6_mba_image = "mba.mbn",
   958	};
   959	
   960	char *proxy_8x16_reg_str[] = {"mx", "cx", "pll"};
   961	char *active_8x16_reg_str[] = {"mss"};
   962	int  proxy_8x16_reg_action[4][2] = { {0, 1}, {1, 0}, {1, 0} };
   963	int  active_8x16_reg_action[1][2] = { {1, 1} };
   964	int  proxy_8x16_reg_load[] = {100000, 0, 100000, 100000};
   965	int  active_8x16_reg_load[] = {100000};
   966	int  proxy_8x16_reg_min_voltage[] = {1050000, 0, 0};
   967	int  active_8x16_reg_min_voltage[] = {1000000};
   968	char *proxy_8x16_clk_str[] = {"xo"};
   969	char *active_8x16_clk_str[] = {"iface", "bus", "mem"};
   970	
   971	static struct q6_rproc_res msm_8916_res = {
   972		.proxy_clks = proxy_8x16_clk_str,
   973		.proxy_clk_cnt = 1,
   974		.active_clks = active_8x16_clk_str,
   975		.active_clk_cnt = 3,
   976		.proxy_regs = proxy_8x16_reg_str,
   977		.active_regs = active_8x16_reg_str,
   978		.proxy_reg_action = (int **)proxy_8x16_reg_action,
   979		.proxy_reg_load = (int *)proxy_8x16_reg_load,
   980		.active_reg_action = (int **)active_8x16_reg_action,
   981		.active_reg_load = (int *)active_8x16_reg_load,
   982		.proxy_reg_voltage = (int *)proxy_8x16_reg_min_voltage,
   983		.active_reg_voltage = active_8x16_reg_min_voltage,
   984		.proxy_reg_cnt = 3,
   985		.active_reg_cnt = 1,
 > 986		.q6_reset_init = q6v5_init_reset,
   987		.q6_version = "v5",
   988		.q6_mba_image = "mba.b00",
   989	};

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 51385 bytes --]

^ permalink raw reply

* Re: [v17 2/2] drm/bridge: Add I2C based driver for ps8640 bridge
From: Daniel Kurtz @ 2016-11-04 23:21 UTC (permalink / raw)
  To: Matthias Brugger
  Cc: Enric Balletbo Serra, Jitao Shi, David Airlie, Thierry Reding,
	Mark Rutland, stonea168, dri-devel, Andy Yan, Ajay Kumar,
	Vincent Palatin, cawa cheng,
	Bibby Hsieh (謝濟遠),
	CK Hu (胡俊光), Russell King,
	devicetree@vger.kernel.org, Sascha Hauer, Pawel Moll,
	Ian Campbell
In-Reply-To: <e00519e2-990c-b9b2-71d4-a4c8d36f5e65@gmail.com>

On Tue, Oct 25, 2016 at 6:23 AM, Matthias Brugger
<matthias.bgg@gmail.com> wrote:
>
> On 10/18/2016 04:37 PM, Enric Balletbo Serra wrote:
> [...]
>>> --- /dev/null
>>> +++ b/drivers/gpu/drm/bridge/parade-ps8640.c
> [...]
>>>
>>> +
>>> +/* Firmware */
>>> +#define PS_FW_NAME             "ps864x_fw.bin"
>>> +
>>
>> From where I can download this firmware image?
>
> I suppose this FW bits have to be added to linux-firmware repository first, before this patch can be accepted.

All PS8640 devices should already ship with working firmware.
The firmware update procedure is only used in the unlikely event where
one wants to update the bridge to a different firmware provided by
Parade.

Why must the lack of firmware really block landing this driver?

If this is really so, can we just land the functional part of the
driver first, and add the firmware update in a follow-up patch.

>
> Regards,
> Matthias

^ permalink raw reply

* Re: [PATCH] Documentation: bindings: fix twl-rtc documentation
From: Alexandre Belloni @ 2016-11-04 23:09 UTC (permalink / raw)
  To: Nicolae Rosia
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	rtc-linux-/JYPxA39Uh5TLH3MbocFFw,
	linux-omap-u79uwXL29TY76Z2rM5mHXA, Rob Herring, Mark Rutland,
	Alessandro Zummo
In-Reply-To: <1477993356-9195-1-git-send-email-Nicolae_Rosia-nmGgyN9QBj3QT0dZR+AlfA@public.gmane.org>

On 01/11/2016 at 11:42:36 +0200, Nicolae Rosia wrote :
> Add interrupts documentation
> Fix example and formatting
> 
> Signed-off-by: Nicolae Rosia <Nicolae_Rosia-nmGgyN9QBj3QT0dZR+AlfA@public.gmane.org>
> ---
>  Documentation/devicetree/bindings/rtc/twl-rtc.txt | 19 +++++++++----------
>  1 file changed, 9 insertions(+), 10 deletions(-)
> 
Applied, thanks.

-- 
Alexandre Belloni, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v3 1/7] rtc: rtc-jz4740: Add support for the RTC in the jz4780 SoC
From: Alexandre Belloni @ 2016-11-04 23:08 UTC (permalink / raw)
  To: Paul Cercueil
  Cc: rtc-linux-/JYPxA39Uh5TLH3MbocFFw, Alessandro Zummo, Rob Herring,
	Mark Rutland, Ralf Baechle, Maarten ter Huurne,
	Lars-Peter Clausen, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-mips-6z/3iImG2C8G8FEW9MqTrA
In-Reply-To: <20161031203951.5444-1-paul-icTtO2rgO2OTuSrc4Mpeew@public.gmane.org>

On 31/10/2016 at 21:39:45 +0100, Paul Cercueil wrote :
> The RTC unit present in the JZ4780 works mostly the same as the one in
> the JZ4740. The major difference is that register writes need to be
> explicitly enabled, by writing a magic code (0xA55A) to a "write
> enable" register before each access.
> 
> Signed-off-by: Paul Cercueil <paul-icTtO2rgO2OTuSrc4Mpeew@public.gmane.org>
> Acked-by: Maarten ter Huurne <maarten-Ph2Y2OKCxY1M656bX5wj8A@public.gmane.org>
> ---
>  drivers/rtc/Kconfig      |  6 +++---
>  drivers/rtc/rtc-jz4740.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++--
>  2 files changed, 51 insertions(+), 5 deletions(-)
> 
> v2: No change
> v3: No change
> 

All applied, thanks


-- 
Alexandre Belloni, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

-- 
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
--- 
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rtc-linux+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.

^ permalink raw reply

* Re: [PATCH V5] pinctrl: qcom: Add msm8994 pinctrl driver
From: Linus Walleij @ 2016-11-04 22:58 UTC (permalink / raw)
  To: Michael Scott
  Cc: linux-gpio@vger.kernel.org, linux-arm-msm@vger.kernel.org,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
	Rob Herring, Mark Rutland, Andy Gross, David Brown,
	Bjorn Andersson, Joonwoo Park, Jeremy McNicoll, Stephen Boyd
In-Reply-To: <20161103211526.6095-1-michael.scott@linaro.org>

On Thu, Nov 3, 2016 at 10:15 PM, Michael Scott <michael.scott@linaro.org> wrote:

> Initial pinctrl driver for QCOM msm8994 platforms.
>
> In order to continue the initial board support for QCOM msm8994/msm8992
> presented in patches from Jeremy McNicoll <jeremymc@redhat.com>, let's put
> a proper pinctrl driver in place.
>
> Currently, the DT for these platforms uses the msm8x74 pinctrl driver to
> enable basic UART.  Beyond the first few pins the rest are different enough
> to justify it's own driver.
>
> Note: This driver is also used by QCOM's msm8992 platform as it's TLM block
> is the same.
>
> - Initial formatting and style was taken from the msm8x74 pinctrl driver
>   added by Björn Andersson <bjorn.andersson@linaro.org>
> - Data was then adjusted per QCOM MSM8994v2 documentation for Top Level
>   Multiplexing
> - Bindings documentation was based on qcom,msm8996-pinctrl.txt by
>   Joonwoo Park <joonwoop@codeaurora.org> and then modified for msm8994
>   content
>
> Signed-off-by: Michael Scott <michael.scott@linaro.org>
> Tested-by: Jeremy McNicoll <jeremymc@redhat.com>
> Acked-by: Bjorn Andersson <bjorn.andersson@linaro.org>
> Acked-by: Rob Herring <robh@kernel.org>
> ---
> V5:

This v5 version applied.

Yours,
Linus Walleij

^ permalink raw reply

* Re: [PATCH 1/2] pinctrl: tegra: Add DT binding for io pads control
From: Linus Walleij @ 2016-11-04 22:29 UTC (permalink / raw)
  To: Laxman Dewangan
  Cc: thierry.reding@gmail.com, Stephen Warren, Rob Herring,
	Mark Rutland, Jon Hunter, Masahiro Yamada,
	linux-gpio@vger.kernel.org, devicetree@vger.kernel.org,
	linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <1478077742-25437-2-git-send-email-ldewangan@nvidia.com>

On Wed, Nov 2, 2016 at 10:09 AM, Laxman Dewangan <ldewangan@nvidia.com> wrote:

> NVIDIA Tegra124 and later SoCs support the multi-voltage level and
> low power state of some of its IO pads. The IO pads can work in
> the voltage of the 1.8V and 3.3V of IO power rail sources. When IO
> interface are not used then IO pads can be configure in low power
> state to reduce the power from that IO pads.
>
> On Tegra124, the IO power rail source is auto detected by SoC and hence
> it is only require to configure in low power mode if IO pads are not
> used.
>
> On T210 onwards, the auto-detection is removed from SoC and hence SW
> must configure the PMC register explicitly to set proper voltage in
> IO pads based on IO rail power source voltage.
>
> Add DT binding document for detailing the DT properties for
> configuring IO pads voltage levels and its power state.
>
> Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
(...)

> +-nvidia,power-source-voltage:  Integer. The voltage level of IO pads. The
> +                               valid values are 1.8V and 3.3V. Macros are
> +                               defined for these voltage levels in
> +                               <dt-bindings/pinctrl/pinctrl-tegra-io-pad.h>
> +                               Use TEGRA_IO_PAD_POWER_SOURCE_1800000UV for 1.8V
> +                               Use TEGRA_IO_PAD_POWER_SOURCE_3300000UV for 3.3V
> +
> +                               All IO pads do not support the 1.8V/3.3V
> +                               configurations. Valid values for "pins" are
> +                               audio-hv, dmic, gpio, sdmmc1, sdmmc3, spi-hv.


As mentioned in another patch, what is wrong with the standard
power-source binding?

Yours,
Linus Walleij

^ permalink raw reply

* Re: [PATCH 2/2] pinctrl: tegra: Add driver to configure voltage and power of io pads
From: Linus Walleij @ 2016-11-04 22:24 UTC (permalink / raw)
  To: Laxman Dewangan
  Cc: thierry.reding@gmail.com, Stephen Warren, Rob Herring,
	Mark Rutland, Jon Hunter, Masahiro Yamada,
	linux-gpio@vger.kernel.org, devicetree@vger.kernel.org,
	linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <1478077742-25437-3-git-send-email-ldewangan@nvidia.com>

On Wed, Nov 2, 2016 at 10:09 AM, Laxman Dewangan <ldewangan@nvidia.com> wrote:

> NVIDIA Tegra124 and later SoCs support the multi-voltage level and
> low power state of some of its IO pads. The IO pads can work in
> the voltage of the 1.8V and 3.3V of IO power rail sources. When IO
> interface are not used then IO pads can be configure in low power
> state to reduce the power from that IO pads.
>
> On Tegra124, the IO power rail source is auto detected by SoC and hence
> it is only require to configure in low power mode if IO pads are not
> used.
>
> On T210 onwards, the auto-detection is removed from SoC and hence SW
> must configure the PMC register explicitly to set proper voltage in
> IO pads based on IO rail power source voltage.
>
> This driver adds the IO pad driver to configure the power state and
> IO pad voltage based on the usage and power tree via pincontrol
> framework. The configuration can be static and dynamic.
>
> Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>

Looking for an ACK from Stephen &| Thierry.

> ---
> On top of the branch from Thierry's T186 work
>         https://github.com/thierryreding/linux/tree/tegra186

But it's an orthogonal patch right?

The build robot seems to have problems with it so pls fix these.

> +static const struct pinconf_generic_params tegra_io_pads_cfg_params[] = {
> +       {
> +               .property = "nvidia,power-source-voltage",
> +               .param = TEGRA_IO_PAD_POWER_SOURCE_VOLTAGE,
> +       },
> +};

Why can you not use the standard power-source binding
from Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
instead of inventing this nvidia,* variant?

Yours,
Linus Walleij

^ permalink raw reply

* Re: [PATCH v2 2/3] irqchip: mtk-cirq: Add mediatek mtk-cirq implement
From: Marc Zyngier @ 2016-11-04 22:21 UTC (permalink / raw)
  To: Youlin Pei
  Cc: Rob Herring, Matthias Brugger, Thomas Gleixner, Jason Cooper,
	Mark Rutland, Russell King, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	srv_heupstream-NuS5LvNUpcJWk0Htik3J/w,
	hongkun.cao-NuS5LvNUpcJWk0Htik3J/w,
	yong.wu-NuS5LvNUpcJWk0Htik3J/w, erin.lo-NuS5LvNUpcJWk0Htik3J/w,
	chieh-jay.liu-NuS5LvNUpcJWk0Htik3J/w
In-Reply-To: <1478234577.7975.29.camel@mtksdaap41>

On Fri, Nov 04 2016 at 04:42:57 AM, Youlin Pei <youlin.pei-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org> wrote:
> On Tue, 2016-11-01 at 20:49 +0000, Marc Zyngier wrote:
>> On Tue, Nov 01 2016 at 11:52:01 AM, Youlin Pei <youlin.pei-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org> wrote:
>> > In Mediatek SOCs, the CIRQ is a low power interrupt controller
>> > designed to works outside MCUSYS which comprises with Cortex-Ax
>> > cores,CCI and GIC.
>> >
>> > The CIRQ controller is integrated in between MCUSYS( include
>> > Cortex-Ax, CCI and GIC ) and interrupt sources as the second
>> > level interrupt controller. The external interrupts which outside
>> > MCUSYS will feed through CIRQ then bypass to GIC. CIRQ can monitors
>> > all edge trigger interupts. When an edge interrupt is triggered,
>> > CIRQ can record the status and generate a pulse signal to GIC when
>> > flush command executed.
>> >
>> > When system enters sleep mode, MCUSYS will be turned off to improve
>> > power consumption, also GIC is power down. The edge trigger interrupts
>> > will be lost in this scenario without CIRQ.
>> >
>> > This commit provides the CIRQ irqchip implement.
>> >
>> > Signed-off-by: Youlin Pei <youlin.pei-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
>> > ---
>> >  drivers/irqchip/Makefile       |    2 +-
>> >  drivers/irqchip/irq-mtk-cirq.c |  262 ++++++++++++++++++++++++++++++++++++++++
>> >  2 files changed, 263 insertions(+), 1 deletion(-)
>> >  create mode 100644 drivers/irqchip/irq-mtk-cirq.c
>> >
>> > diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
>> > index e4dbfc8..8f33580 100644
>> > --- a/drivers/irqchip/Makefile
>> > +++ b/drivers/irqchip/Makefile
>> > @@ -60,7 +60,7 @@ obj-$(CONFIG_BCM7120_L2_IRQ)		+= irq-bcm7120-l2.o
>> >  obj-$(CONFIG_BRCMSTB_L2_IRQ)		+= irq-brcmstb-l2.o
>> >  obj-$(CONFIG_KEYSTONE_IRQ)		+= irq-keystone.o
>> >  obj-$(CONFIG_MIPS_GIC)			+= irq-mips-gic.o
>> > -obj-$(CONFIG_ARCH_MEDIATEK)		+= irq-mtk-sysirq.o
>> > +obj-$(CONFIG_ARCH_MEDIATEK)		+= irq-mtk-sysirq.o irq-mtk-cirq.o
>> >  obj-$(CONFIG_ARCH_DIGICOLOR)		+= irq-digicolor.o
>> >  obj-$(CONFIG_RENESAS_H8300H_INTC)	+= irq-renesas-h8300h.o
>> >  obj-$(CONFIG_RENESAS_H8S_INTC)		+= irq-renesas-h8s.o
>> > diff --git a/drivers/irqchip/irq-mtk-cirq.c b/drivers/irqchip/irq-mtk-cirq.c
>> > new file mode 100644
>> > index 0000000..fc43ef3
>> > --- /dev/null
>> > +++ b/drivers/irqchip/irq-mtk-cirq.c
>> > @@ -0,0 +1,262 @@
>> > +/*
>> > + * Copyright (c) 2016 MediaTek Inc.
>> > + * Author: Youlin.Pei <youlin.pei-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
>> > + *
>> > + * This program is free software; you can redistribute it and/or modify
>> > + * it under the terms of the GNU General Public License version 2 as
>> > + * published by the Free Software Foundation.
>> > + *
>> > + * This program is distributed in the hope that it will be useful,
>> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> > + * GNU General Public License for more details.
>> > + */
>> > +
>> > +#include <linux/irq.h>
>> > +#include <linux/irqchip.h>
>> > +#include <linux/irqdomain.h>
>> > +#include <linux/of.h>
>> > +#include <linux/of_irq.h>
>> > +#include <linux/of_address.h>
>> > +#include <linux/io.h>
>> > +#include <linux/slab.h>
>> > +#include <linux/syscore_ops.h>
>> > +
>> > +#define CIRQ_ACK	0x40
>> > +#define CIRQ_MASK_SET	0xc0
>> > +#define CIRQ_MASK_CLR	0x100
>> > +#define CIRQ_SENS_SET	0x180
>> > +#define CIRQ_SENS_CLR	0x1c0
>> > +#define CIRQ_POL_SET	0x240
>> > +#define CIRQ_POL_CLR	0x280
>> > +#define CIRQ_CONTROL	0x300
>> > +
>> > +#define CIRQ_EN	0x1
>> > +#define CIRQ_EDGE	0x2
>> > +#define CIRQ_FLUSH	0x4
>> > +
>> > +#define CIRQ_IRQ_NUM    0x200
>> > +
>> > +struct mtk_cirq_chip_data {
>> > +	void __iomem *base;
>> > +	unsigned int ext_irq_start;
>> > +};
>> > +
>> > +static struct mtk_cirq_chip_data *cirq_data;
>> 
>> Are you guaranteed that you'll only ever have a single CIRQ in any
>> system?
>
> In Mediatek's SOC, only hace a single CIRQ.
>
>> 
>> > +
>> > +static void mtk_cirq_write_mask(struct irq_data *data, unsigned int offset)
>> > +{
>> > +	struct mtk_cirq_chip_data *chip_data = data->chip_data;
>> > +	unsigned int cirq_num = data->hwirq;
>> > +	u32 mask = 1 << (cirq_num % 32);
>> > +
>> > +	writel(mask, chip_data->base + offset + (cirq_num / 32) * 4);
>> 
>> Why can't you use the relaxed accessors?
>
> It seems that i use wrong function, i will change the writel to
> writel_relaxed in next version.
>
>> 
>> > +}
>> > +
>> > +static void mtk_cirq_mask(struct irq_data *data)
>> > +{
>> > +	mtk_cirq_write_mask(data, CIRQ_MASK_SET);
>> > +	irq_chip_mask_parent(data);
>> > +}
>> > +
>> > +static void mtk_cirq_unmask(struct irq_data *data)
>> > +{
>> > +	mtk_cirq_write_mask(data, CIRQ_MASK_CLR);
>> > +	irq_chip_unmask_parent(data);
>> > +}
>> > +
>> > +static void mtk_cirq_eoi(struct irq_data *data)
>> > +{
>> > +	mtk_cirq_write_mask(data, CIRQ_ACK);
>> 
>> EOI and ACK have very different semantics. What is this write actually
>> doing? Also, you're now doing an additional MMIO write on each interrupt
>> EOI, doubling its cost. Do you really need to do actually signal the HW
>> that we've EOIed an interrupt? I would have hoped that you'd be able to
>> put it in "bypass" mode as long as you're not suspending...
>> 
>
> When external interrupt happened, CIRQ status register record the status
> even CIRQ is not enabled. when execute the flush command, CIRQ will
> resend the signals according to the status. So if don't clear the
> status, CIRQ will resend the wrong signals. the ACK write operation will
> clear the status.

But at this time, we haven't suspended yet, and there is nothing to
replay. Also, you only enable the edge capture when suspending. So what
are you ACKing here? Can't you simply clear everything right when
suspending and not do it at all on the fast path?

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH] pinctrl: meson: Add GXL pinctrl definitions
From: Linus Walleij @ 2016-11-04 22:07 UTC (permalink / raw)
  To: Neil Armstrong
  Cc: Kevin Hilman, Carlo Caione, linux-gpio@vger.kernel.org,
	open list:ARM/Amlogic Meson...,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, devicetree@vger.kernel.org
In-Reply-To: <1477931531-27120-1-git-send-email-narmstrong@baylibre.com>

On Mon, Oct 31, 2016 at 5:32 PM, Neil Armstrong <narmstrong@baylibre.com> wrote:

> Add support for the Amlogic Meson GXL SoC, this is a partially complete
> definition only based on the Amlogic Vendor tree.
>
> This definition differs a lot from the GXBB and needs a separate entry.
>
> Acked-by: Rob Herring <robh@kernel.org>
> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>

Patch applied with Kevin's ACK.

Yours,
Linus Walleij

^ permalink raw reply

* [PATCH v2 11/11] ARM: dts: sk-rzg1e: add Ether support
From: Sergei Shtylyov @ 2016-11-04 22:05 UTC (permalink / raw)
  To: horms, linux-renesas-soc, robh+dt, mark.rutland, devicetree
  Cc: magnus.damm, linux, linux-arm-kernel
In-Reply-To: <2368353.xfo5beGC5E@wasted.cogentembedded.com>

Define the SK-RZG1E board dependent part of the Ether device node.
Enable DHCP and NFS root  for the kernel booting.

Based on the original (and large) patch by Dmitry Shifrin
<dmitry.shifrin@cogentembedded.com>.

Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>

---
Changes in version 2:
- added Geert's tag.

 arch/arm/boot/dts/r8a7745-sk-rzg1e.dts |   15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

Index: renesas/arch/arm/boot/dts/r8a7745-sk-rzg1e.dts
===================================================================
--- renesas.orig/arch/arm/boot/dts/r8a7745-sk-rzg1e.dts
+++ renesas/arch/arm/boot/dts/r8a7745-sk-rzg1e.dts
@@ -20,7 +20,7 @@
 	};
 
 	chosen {
-		bootargs = "ignore_loglevel";
+		bootargs = "ignore_loglevel rw root=/dev/nfs ip=dhcp";
 		stdout-path = "serial0:115200n8";
 	};
 
@@ -37,3 +37,16 @@
 &scif2 {
 	status = "okay";
 };
+
+&ether {
+	phy-handle = <&phy1>;
+	renesas,ether-link-active-low;
+	status = "okay";
+
+	phy1: ethernet-phy@1 {
+		reg = <1>;
+		interrupt-parent = <&irqc>;
+		interrupts = <8 IRQ_TYPE_LEVEL_LOW>;
+		micrel,led-mode = <1>;
+	};
+};

^ permalink raw reply

* [PATCH v2 10/11] ARM: dts: sk-rzg1e: initial device tree
From: Sergei Shtylyov @ 2016-11-04 22:04 UTC (permalink / raw)
  To: horms, linux-renesas-soc, robh+dt, mark.rutland, devicetree
  Cc: magnus.damm, linux, linux-arm-kernel
In-Reply-To: <2368353.xfo5beGC5E@wasted.cogentembedded.com>

Add the initial  device tree for the R8A7745 SoC based SK-RZG1E board.
The board has 1  debug  serial  port (SCIF2); include support for it,
so that the serial console can  work.

Based on the original (and large) patch by Dmitry Shifrin
<dmitry.shifrin@cogentembedded.com>.

Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>

---
Changes in version 2:
- added Geert's tag.

 arch/arm/boot/dts/Makefile             |    1 
 arch/arm/boot/dts/r8a7745-sk-rzg1e.dts |   39 +++++++++++++++++++++++++++++++++
 2 files changed, 40 insertions(+)

Index: renesas/arch/arm/boot/dts/Makefile
===================================================================
--- renesas.orig/arch/arm/boot/dts/Makefile
+++ renesas/arch/arm/boot/dts/Makefile
@@ -678,6 +678,7 @@ dtb-$(CONFIG_ARCH_SHMOBILE_MULTI) += \
 	r8a73a4-ape6evm.dtb \
 	r8a7740-armadillo800eva.dtb \
 	r8a7743-sk-rzg1m.dtb \
+	r8a7745-sk-rzg1e.dtb \
 	r8a7778-bockw.dtb \
 	r8a7779-marzen.dtb \
 	r8a7790-lager.dtb \
Index: renesas/arch/arm/boot/dts/r8a7745-sk-rzg1e.dts
===================================================================
--- /dev/null
+++ renesas/arch/arm/boot/dts/r8a7745-sk-rzg1e.dts
@@ -0,0 +1,39 @@
+/*
+ * Device Tree Source for the SK-RZG1E board
+ *
+ * Copyright (C) 2016 Cogent Embedded, Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+/dts-v1/;
+#include "r8a7745.dtsi"
+
+/ {
+	model = "SK-RZG1E";
+	compatible = "renesas,sk-rzg1e", "renesas,r8a7745";
+
+	aliases {
+		serial0 = &scif2;
+	};
+
+	chosen {
+		bootargs = "ignore_loglevel";
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory@40000000 {
+		device_type = "memory";
+		reg = <0 0x40000000 0 0x40000000>;
+	};
+};
+
+&extal_clk {
+	clock-frequency = <20000000>;
+};
+
+&scif2 {
+	status = "okay";
+};

^ permalink raw reply

* [PATCH v2 09/11] ARM: shmobile: document SK-RZG1E board
From: Sergei Shtylyov @ 2016-11-04 22:02 UTC (permalink / raw)
  To: horms, linux-renesas-soc, robh+dt, mark.rutland, devicetree
In-Reply-To: <2368353.xfo5beGC5E@wasted.cogentembedded.com>

Document the SK-RZG1E device tree bindings, listing it as a supported board.

This allows to use checkpatch.pl to validate .dts files referring to the
SK-RZG1E board.

Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>

---
Changes in version 2:
- fixed the subject;
- added Geert's tag.

 Documentation/devicetree/bindings/arm/shmobile.txt |    2 ++
 1 file changed, 2 insertions(+)

Index: renesas/Documentation/devicetree/bindings/arm/shmobile.txt
===================================================================
--- renesas.orig/Documentation/devicetree/bindings/arm/shmobile.txt
+++ renesas/Documentation/devicetree/bindings/arm/shmobile.txt
@@ -77,6 +77,8 @@ Boards:
     compatible = "renesas,salvator-x", "renesas,r8a7796";
   - SILK (RTP0RC7794LCB00011S)
     compatible = "renesas,silk", "renesas,r8a7794"
+  - SK-RZG1E (YR8A77450S000BE)
+    compatible = "renesas,sk-rzg1e", "renesas,r8a7745"
   - SK-RZG1M (YR8A77430S000BE)
     compatible = "renesas,sk-rzg1m", "renesas,r8a7743"
   - Wheat

^ permalink raw reply

* [PATCH v2 08/11] ARM: dts: r8a7745: add IRQC support
From: Sergei Shtylyov @ 2016-11-04 21:59 UTC (permalink / raw)
  To: horms-/R6kz+dDXgpPR4JQBCEnsQ,
	linux-renesas-soc-u79uwXL29TY76Z2rM5mHXA,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: magnus.damm-Re5JQEeQqe8AvxtiuMwx3w, linux-lFZ/pmaqli7XmaaqVzeoHQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <2368353.xfo5beGC5E-gHKXc3Y1Z8zGSmamagVegGFoWSdPRAKMAL8bYrjMMd8@public.gmane.org>

Describe the IRQC interrupt controller in the R8A7745 device tree.

Based on the original (and large) patch by Dmitry Shifrin
<dmitry.shifrin-M4DtvfQ/ZS1MRgGoP+s0PdBPR1lH4CV8@public.gmane.org>.

Signed-off-by: Sergei Shtylyov <sergei.shtylyov-M4DtvfQ/ZS1MRgGoP+s0PdBPR1lH4CV8@public.gmane.org>
Reviewed-by: Geert Uytterhoeven <geert+renesas-gXvu3+zWzMSzQB+pC5nmwQ@public.gmane.org>

---
Changes in version 2:
- added Geert's tag;
- refreshed the patch.

 arch/arm/boot/dts/r8a7745.dtsi |   19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

Index: renesas/arch/arm/boot/dts/r8a7745.dtsi
===================================================================
--- renesas.orig/arch/arm/boot/dts/r8a7745.dtsi
+++ renesas/arch/arm/boot/dts/r8a7745.dtsi
@@ -62,6 +62,25 @@
 						 IRQ_TYPE_LEVEL_HIGH)>;
 		};
 
+		irqc: interrupt-controller@e61c0000 {
+			compatible = "renesas,irqc-r8a7745", "renesas,irqc";
+			#interrupt-cells = <2>;
+			interrupt-controller;
+			reg = <0 0xe61c0000 0 0x200>;
+			interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 407>;
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+		};
+
 		timer {
 			compatible = "arm,armv7-timer";
 			interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) |

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH v2 07/11] ARM: dts: r8a7745: add Ether support
From: Sergei Shtylyov @ 2016-11-04 21:57 UTC (permalink / raw)
  To: horms, linux-renesas-soc, robh+dt, mark.rutland, devicetree
  Cc: magnus.damm, linux, linux-arm-kernel
In-Reply-To: <2368353.xfo5beGC5E@wasted.cogentembedded.com>

Define the generic R8A7745 part of the Ether device node.

Based on the original (and large) patch by Dmitry Shifrin
<dmitry.shifrin@cogentembedded.com>.

Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>

---
Changes in version 2:
- added Geert's tag.

 arch/arm/boot/dts/r8a7745.dtsi |   12 ++++++++++++
 1 file changed, 12 insertions(+)

Index: renesas/arch/arm/boot/dts/r8a7745.dtsi
===================================================================
--- renesas.orig/arch/arm/boot/dts/r8a7745.dtsi
+++ renesas/arch/arm/boot/dts/r8a7745.dtsi
@@ -418,6 +418,18 @@
 			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
 			status = "disabled";
 		};
+
+		ether: ethernet@ee700000 {
+			compatible = "renesas,ether-r8a7745";
+			reg = <0 0xee700000 0 0x400>;
+			interrupts = <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 813>;
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			phy-mode = "rmii";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
 	};
 
 	/* External root clock */

^ permalink raw reply

* [PATCH v2 06/11] ARM: dts: r8a7745: add [H]SCIF{|A|B} support
From: Sergei Shtylyov @ 2016-11-04 21:55 UTC (permalink / raw)
  To: horms, linux-renesas-soc, robh+dt, mark.rutland, devicetree
  Cc: magnus.damm, linux, linux-arm-kernel
In-Reply-To: <2368353.xfo5beGC5E@wasted.cogentembedded.com>

Describe [H]SCIF{|A|B} ports in the R8A7745 device tree.

Based on the original (and large) patch by Dmitry Shifrin
<dmitry.shifrin@cogentembedded.com>.

Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>

---
Changes in version 2:
- used the R-Car gen2 bindings instead of the RZ/G family ones;
- added Geert's tag.

 arch/arm/boot/dts/r8a7745.dtsi |  261 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 261 insertions(+)

Index: renesas/arch/arm/boot/dts/r8a7745.dtsi
===================================================================
--- renesas.orig/arch/arm/boot/dts/r8a7745.dtsi
+++ renesas/arch/arm/boot/dts/r8a7745.dtsi
@@ -157,6 +157,267 @@
 			#dma-cells = <1>;
 			dma-channels = <15>;
 		};
+
+		scifa0: serial@e6c40000 {
+			compatible = "renesas,scifa-r8a7745",
+				     "renesas,rcar-gen2-scifa", "renesas,scifa";
+			reg = <0 0xe6c40000 0 0x40>;
+			interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 204>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x21>, <&dmac0 0x22>,
+			       <&dmac1 0x21>, <&dmac1 0x22>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		scifa1: serial@e6c50000 {
+			compatible = "renesas,scifa-r8a7745",
+				     "renesas,rcar-gen2-scifa", "renesas,scifa";
+			reg = <0 0xe6c50000 0 0x40>;
+			interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 203>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x25>, <&dmac0 0x26>,
+			       <&dmac1 0x25>, <&dmac1 0x26>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		scifa2: serial@e6c60000 {
+			compatible = "renesas,scifa-r8a7745",
+				     "renesas,rcar-gen2-scifa", "renesas,scifa";
+			reg = <0 0xe6c60000 0 0x40>;
+			interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 202>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x27>, <&dmac0 0x28>,
+			       <&dmac1 0x27>, <&dmac1 0x28>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		scifa3: serial@e6c70000 {
+			compatible = "renesas,scifa-r8a7745",
+				     "renesas,rcar-gen2-scifa", "renesas,scifa";
+			reg = <0 0xe6c70000 0 0x40>;
+			interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 1106>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x1b>, <&dmac0 0x1c>,
+			       <&dmac1 0x1b>, <&dmac1 0x1c>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		scifa4: serial@e6c78000 {
+			compatible = "renesas,scifa-r8a7745",
+				     "renesas,rcar-gen2-scifa", "renesas,scifa";
+			reg = <0 0xe6c78000 0 0x40>;
+			interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 1107>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x1f>, <&dmac0 0x20>,
+			       <&dmac1 0x1f>, <&dmac1 0x20>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		scifa5: serial@e6c80000 {
+			compatible = "renesas,scifa-r8a7745",
+				     "renesas,rcar-gen2-scifa", "renesas,scifa";
+			reg = <0 0xe6c80000 0 0x40>;
+			interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 1108>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x23>, <&dmac0 0x24>,
+			       <&dmac1 0x23>, <&dmac1 0x24>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		scifb0: serial@e6c20000 {
+			compatible = "renesas,scifb-r8a7745",
+				     "renesas,rcar-gen2-scifb", "renesas,scifb";
+			reg = <0 0xe6c20000 0 0x100>;
+			interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 206>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x3d>, <&dmac0 0x3e>,
+		       <&dmac1 0x3d>, <&dmac1 0x3e>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		scifb1: serial@e6c30000 {
+			compatible = "renesas,scifb-r8a7745",
+				     "renesas,rcar-gen2-scifb", "renesas,scifb";
+			reg = <0 0xe6c30000 0 0x100>;
+			interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 207>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x19>, <&dmac0 0x1a>,
+			       <&dmac1 0x19>, <&dmac1 0x1a>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		scifb2: serial@e6ce0000 {
+			compatible = "renesas,scifb-r8a7745",
+				     "renesas,rcar-gen2-scifb", "renesas,scifb";
+			reg = <0 0xe6ce0000 0 0x100>;
+			interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 216>;
+			clock-names = "fck";
+			dmas = <&dmac0 0x1d>, <&dmac0 0x1e>,
+			       <&dmac1 0x1d>, <&dmac1 0x1e>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		scif0: serial@e6e60000 {
+			compatible = "renesas,scif-r8a7745",
+				     "renesas,rcar-gen2-scif", "renesas,scif";
+			reg = <0 0xe6e60000 0 0x40>;
+			interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 721>,
+			         <&cpg CPG_CORE R8A7745_CLK_ZS>, <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x29>, <&dmac0 0x2a>,
+			       <&dmac1 0x29>, <&dmac1 0x2a>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		scif1: serial@e6e68000 {
+			compatible = "renesas,scif-r8a7745",
+				     "renesas,rcar-gen2-scif", "renesas,scif";
+			reg = <0 0xe6e68000 0 0x40>;
+			interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 720>,
+			         <&cpg CPG_CORE R8A7745_CLK_ZS>, <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x2d>, <&dmac0 0x2e>,
+			       <&dmac1 0x2d>, <&dmac1 0x2e>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		scif2: serial@e6e58000 {
+			compatible = "renesas,scif-r8a7745",
+				     "renesas,rcar-gen2-scif", "renesas,scif";
+			reg = <0 0xe6e58000 0 0x40>;
+			interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 719>,
+			         <&cpg CPG_CORE R8A7745_CLK_ZS>, <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x2b>, <&dmac0 0x2c>,
+			       <&dmac1 0x2b>, <&dmac1 0x2c>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		scif3: serial@e6ea8000 {
+			compatible = "renesas,scif-r8a7745",
+				     "renesas,rcar-gen2-scif", "renesas,scif";
+			reg = <0 0xe6ea8000 0 0x40>;
+			interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 718>,
+			         <&cpg CPG_CORE R8A7745_CLK_ZS>, <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x2f>, <&dmac0 0x30>,
+			       <&dmac1 0x2f>, <&dmac1 0x30>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		scif4: serial@e6ee0000 {
+			compatible = "renesas,scif-r8a7745",
+				     "renesas,rcar-gen2-scif", "renesas,scif";
+			reg = <0 0xe6ee0000 0 0x40>;
+			interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 715>,
+			         <&cpg CPG_CORE R8A7745_CLK_ZS>, <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0xfb>, <&dmac0 0xfc>,
+			       <&dmac1 0xfb>, <&dmac1 0xfc>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		scif5: serial@e6ee8000 {
+			compatible = "renesas,scif-r8a7745",
+				     "renesas,rcar-gen2-scif", "renesas,scif";
+			reg = <0 0xe6ee8000 0 0x40>;
+			interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 714>,
+			         <&cpg CPG_CORE R8A7745_CLK_ZS>, <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0xfd>, <&dmac0 0xfe>,
+			       <&dmac1 0xfd>, <&dmac1 0xfe>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		hscif0: serial@e62c0000 {
+			compatible = "renesas,hscif-r8a7745",
+				     "renesas,rcar-gen2-hscif", "renesas,hscif";
+			reg = <0 0xe62c0000 0 0x60>;
+			interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 717>,
+			         <&cpg CPG_CORE R8A7745_CLK_ZS>, <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x39>, <&dmac0 0x3a>,
+			       <&dmac1 0x39>, <&dmac1 0x3a>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		hscif1: serial@e62c8000 {
+			compatible = "renesas,hscif-r8a7745",
+				     "renesas,rcar-gen2-hscif", "renesas,hscif";
+			reg = <0 0xe62c8000 0 0x60>;
+			interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 716>,
+			         <&cpg CPG_CORE R8A7745_CLK_ZS>, <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x4d>, <&dmac0 0x4e>,
+			       <&dmac1 0x4d>, <&dmac1 0x4e>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
+
+		hscif2: serial@e62d0000 {
+			compatible = "renesas,hscif-r8a7745",
+				     "renesas,rcar-gen2-hscif", "renesas,hscif";
+			reg = <0 0xe62d0000 0 0x60>;
+			interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 713>,
+			         <&cpg CPG_CORE R8A7745_CLK_ZS>, <&scif_clk>;
+			clock-names = "fck", "brg_int", "scif_clk";
+			dmas = <&dmac0 0x3b>, <&dmac0 0x3c>,
+			       <&dmac1 0x3b>, <&dmac1 0x3c>;
+			dma-names = "tx", "rx", "tx", "rx";
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			status = "disabled";
+		};
 	};
 
 	/* External root clock */

^ permalink raw reply

* Re: [PATCH 4/4] ARM: dts: Add #pinctrl-cells for pinctrl-single instances
From: Linus Walleij @ 2016-11-04 21:55 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Jon Hunter, Mark Rutland, Rob Herring, Grygorii Strashko,
	Nishanth Menon,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Linux-OMAP
In-Reply-To: <20161103163550.27330-5-tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>

On Thu, Nov 3, 2016 at 5:35 PM, Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org> wrote:

> Drivers using pinctrl-single,pins have #pinctrl-cells = <1>, while
> pinctrl-single,bits need #pinctrl-cells = <2>.
>
> Note that this patch can be optionally applied separately from the
> driver changes as the driver supports also the legacy binding without
> #pinctrl-cells.
>
> Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> Signed-off-by: Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>

Reviewed-by: Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>

Please take this through the OMAP tree to avoid hazzle.

Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH v2 05/11] ARM: dts: r8a7745: add SYS-DMAC support
From: Sergei Shtylyov @ 2016-11-04 21:54 UTC (permalink / raw)
  To: horms, linux-renesas-soc, robh+dt, mark.rutland, devicetree
  Cc: magnus.damm, linux, linux-arm-kernel
In-Reply-To: <2368353.xfo5beGC5E@wasted.cogentembedded.com>

Describe SYS-DMAC0/1 in the R8A7745 device tree.

Based on the original (and large) patch by Dmitry Shifrin
<dmitry.shifrin@cogentembedded.com>.

Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>

---
Changes in version 2:
- added Geert's tag;
- refreshed the patch.

 arch/arm/boot/dts/r8a7745.dtsi |   64 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 64 insertions(+)

Index: renesas/arch/arm/boot/dts/r8a7745.dtsi
===================================================================
--- renesas.orig/arch/arm/boot/dts/r8a7745.dtsi
+++ renesas/arch/arm/boot/dts/r8a7745.dtsi
@@ -93,6 +93,70 @@
 			compatible = "renesas,r8a7745-rst";
 			reg = <0 0xe6160000 0 0x0200>;
 		};
+
+		dmac0: dma-controller@e6700000 {
+			compatible = "renesas,dmac-r8a7745",
+				     "renesas,rcar-dmac";
+			reg = <0 0xe6700000 0 0x20000>;
+			interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 210 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error",
+					"ch0", "ch1", "ch2", "ch3",
+					"ch4", "ch5", "ch6", "ch7",
+					"ch8", "ch9", "ch10", "ch11",
+					"ch12", "ch13", "ch14";
+			clocks = <&cpg CPG_MOD 219>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			#dma-cells = <1>;
+			dma-channels = <15>;
+		};
+
+		dmac1: dma-controller@e6720000 {
+			compatible = "renesas,dmac-r8a7745",
+				     "renesas,rcar-dmac";
+			reg = <0 0xe6720000 0 0x20000>;
+			interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 311 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH
+				      GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "error",
+					"ch0", "ch1", "ch2", "ch3",
+					"ch4", "ch5", "ch6", "ch7",
+					"ch8", "ch9", "ch10", "ch11",
+					"ch12", "ch13", "ch14";
+			clocks = <&cpg CPG_MOD 218>;
+			clock-names = "fck";
+			power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+			#dma-cells = <1>;
+			dma-channels = <15>;
+		};
 	};
 
 	/* External root clock */

^ permalink raw reply

* Re: [PATCH 3/4] pinctrl: single: Use generic parser and #pinctrl-cells for pinctrl-single,bits
From: Linus Walleij @ 2016-11-04 21:54 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Jon Hunter, Mark Rutland, Rob Herring, Grygorii Strashko,
	Nishanth Menon,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Linux-OMAP
In-Reply-To: <20161103163550.27330-4-tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>

On Thu, Nov 3, 2016 at 5:35 PM, Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org> wrote:

> We can now use generic parser and keep things compatible with the
> old binding.
>
> Signed-off-by: Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>

V2 Patch applied.

Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH v2 04/11] ARM: dts: r8a7745: initial SoC device tree
From: Sergei Shtylyov @ 2016-11-04 21:53 UTC (permalink / raw)
  To: horms, linux-renesas-soc, robh+dt, mark.rutland, devicetree
  Cc: magnus.damm, linux, linux-arm-kernel
In-Reply-To: <2368353.xfo5beGC5E@wasted.cogentembedded.com>

The  initial R8A7745 SoC device tree including CPU0, GIC, timer, SYSC, RST,
CPG, and the required clock descriptions.

Based on the original (and large) patch by Dmitry Shifrin
<dmitry.shifrin@cogentembedded.com>.

Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>

---
Changes in version 2:
- reformatted the "interrupts" props of the GIC/timer device nodes;
- added Geert's tag.

 arch/arm/boot/dts/r8a7745.dtsi |  120 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 120 insertions(+)

Index: renesas/arch/arm/boot/dts/r8a7745.dtsi
===================================================================
--- /dev/null
+++ renesas/arch/arm/boot/dts/r8a7745.dtsi
@@ -0,0 +1,120 @@
+/*
+ * Device Tree Source for the r8a7745 SoC
+ *
+ * Copyright (C) 2016 Cogent Embedded Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/r8a7745-cpg-mssr.h>
+#include <dt-bindings/power/r8a7745-sysc.h>
+
+/ {
+	compatible = "renesas,r8a7745";
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu0: cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0>;
+			clock-frequency = <1000000000>;
+			clocks = <&cpg CPG_CORE R8A7745_CLK_Z2>;
+			power-domains = <&sysc R8A7745_PD_CA7_CPU0>;
+			next-level-cache = <&L2_CA7>;
+		};
+
+		L2_CA7: cache-controller@0 {
+			compatible = "cache";
+			reg = <0>;
+			cache-unified;
+			cache-level = <2>;
+			power-domains = <&sysc R8A7745_PD_CA7_SCU>;
+		};
+	};
+
+	soc {
+		compatible = "simple-bus";
+		interrupt-parent = <&gic>;
+
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		gic: interrupt-controller@f1001000 {
+			compatible = "arm,gic-400";
+			#interrupt-cells = <3>;
+			#address-cells = <0>;
+			interrupt-controller;
+			reg = <0 0xf1001000 0 0x1000>,
+			      <0 0xf1002000 0 0x1000>,
+			      <0 0xf1004000 0 0x2000>,
+			      <0 0xf1006000 0 0x2000>;
+			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) |
+						 IRQ_TYPE_LEVEL_HIGH)>;
+		};
+
+		timer {
+			compatible = "arm,armv7-timer";
+			interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) |
+						  IRQ_TYPE_LEVEL_LOW)>,
+				     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) |
+						  IRQ_TYPE_LEVEL_LOW)>,
+				     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) |
+						  IRQ_TYPE_LEVEL_LOW)>,
+				     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) |
+						  IRQ_TYPE_LEVEL_LOW)>;
+		};
+
+		cpg: clock-controller@e6150000 {
+			compatible = "renesas,r8a7745-cpg-mssr";
+			reg = <0 0xe6150000 0 0x1000>;
+			clocks = <&extal_clk>, <&usb_extal_clk>;
+			clock-names = "extal", "usb_extal";
+			#clock-cells = <2>;
+			#power-domain-cells = <0>;
+		};
+
+		sysc: system-controller@e6180000 {
+			compatible = "renesas,r8a7745-sysc";
+			reg = <0 0xe6180000 0 0x200>;
+			#power-domain-cells = <1>;
+		};
+
+		rst: reset-controller@e6160000 {
+			compatible = "renesas,r8a7745-rst";
+			reg = <0 0xe6160000 0 0x100>;
+		};
+	};
+
+	/* External root clock */
+	extal_clk: extal {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		/* This value must be overridden by the board. */
+		clock-frequency = <0>;
+	};
+
+	/* External USB clock - can be overridden by the board */
+	usb_extal_clk: usb_extal {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <48000000>;
+	};
+
+	/* External SCIF clock */
+	scif_clk: scif {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		/* This value must be overridden by the board. */
+		clock-frequency = <0>;
+	};
+};

^ permalink raw reply

* Re: [PATCH 2/4] pinctrl: single: Use generic parser and #pinctrl-cells for pinctrl-single,pins
From: Linus Walleij @ 2016-11-04 21:52 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Jon Hunter, Mark Rutland, Rob Herring, Grygorii Strashko,
	Nishanth Menon, linux-gpio@vger.kernel.org,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
	Linux-OMAP
In-Reply-To: <20161103163550.27330-3-tony@atomide.com>

On Thu, Nov 3, 2016 at 5:35 PM, Tony Lindgren <tony@atomide.com> wrote:

> We can now use generic parser. To support the legacy binding without
> #pinctrl-cells, add pcs_quirk_missing_pinctrl_cells() and warn about
> missing #pinctrl-cells.
>
> Let's also update the documentation for struct pcs_soc_data while at it
> as that seems to be out of date.
>
> Signed-off-by: Tony Lindgren <tony@atomide.com>

This v2 patch applied.

Yours,
Linus Walleij

^ 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