Browse Source

Merge pull request #171 in PROCESSOR-SDK/processor-sdk-linux from plsdk-2750 to processor-sdk-linux-4.19.y

* commit '3c4238882bee4590cb0b6d69c3ee4f96ad7efd38':
  net: ethernet: ti: ptp_bc: make pps_mux_sel gpios optional
  net: ethernet: ti: cpts: enhance pps gen/latch operations
  arm: dts: am57[1,2,4]x-idk-pps: break timers into pps_timer and latch_timer
  arm: dts: am57[1,2,4]x-idk-pps: use PIN_OUTPUT_PULLDOWN for off state
  dt-bindings: net : ptp_bc: Document optional parameter pps-sel[0,1]-gpios
  dt-bindings: net: ti-prueth: Document the optional pinctrl parameters for SYNC/LATCH signal
  dt-bindings: net: cpsw: document PPS related optional parameters
Eric Ruei 6 years ago
parent
commit
451dc9ea47

+ 31 - 0
Documentation/devicetree/bindings/net/cpsw.txt

@@ -54,6 +54,18 @@ Optional properties:
 - mac-address		: See ethernet.txt file in the same directory
 - mac-address		: See ethernet.txt file in the same directory
 - phy_id		: Specifies slave phy id (deprecated, use phy-handle)
 - phy_id		: Specifies slave phy id (deprecated, use phy-handle)
 - phy-handle		: See ethernet.txt file in the same directory
 - phy-handle		: See ethernet.txt file in the same directory
+- pps_timer		: phandle, referring to the DM timer for PPS generation
+- latch_timer	: phandle, phandle, referring to the DM timer for PPS latch
+- pinctrl-names	: List of assigned state names,
+				  see pinctrl binding documentation.
+- pinctrl-0: phandle, referring to the PPS signal on configuration node.
+- pinctrl-1: phandle, referring to the PPS signal off configuration node.
+- pinctrl-2: phandle, referring to the PPS ref signal on configuration node.
+- pinctrl-3: phandle, referring to the PPS ref signal off configuration node.
+- pinctrl-4: phandle, referring to the PPS latch signal on configuration node.
+- pinctrl-5: phandle, referring to the PPS latch signal off configuration node.
+- pps-enable-gpios	: GPIO specifier, used to enable PPS signal output
+- ref-enable-gpios	: GPIO specifier, used to enable PPS ref signal output
 
 
 Slave sub-nodes:
 Slave sub-nodes:
 - fixed-link		: See fixed-link.txt file in the same directory
 - fixed-link		: See fixed-link.txt file in the same directory
@@ -126,3 +138,22 @@ Examples:
 			mac-address = [ 00 00 00 00 00 00 ];
 			mac-address = [ 00 00 00 00 00 00 ];
 		};
 		};
 	};
 	};
+
+
+(plus)
+&mac {
+	/* cptr pps1 generator and latch properties */
+	pps_timer = <&timer16>;
+	latch_timer = <&timer15>;
+	pinctrl-names = "pwm_off", "pwm_on", "ref_off", "ref_on",
+			"latch_on", "latch_off";
+	pinctrl-0 = <&pps1_timer16_pwm_off>;
+	pinctrl-1 = <&pps1_timer16_pwm_on>;
+	pinctrl-2 = <&pps1_timer16_pwm2_off>;
+	pinctrl-3 = <&pps1_timer16_pwm2_on>;
+	pinctrl-4 = <&pps1_timer15_latch_on>;
+	pinctrl-5 = <&pps1_timer15_latch_off>;
+
+	pps-enable-gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
+	ref-enable-gpios = <&gpio6 19 GPIO_ACTIVE_HIGH>;
+};

+ 19 - 2
Documentation/devicetree/bindings/net/ti-prueth.txt

@@ -32,6 +32,12 @@ Optional properties:
 		     should be "rx_red_hp", "rx_red_lp".
 		     should be "rx_red_hp", "rx_red_lp".
 - interrupts       : should contain an array of PRUSS system event
 - interrupts       : should contain an array of PRUSS system event
                      numbers.
                      numbers.
+- pinctrl-names	: List of assigned state names,
+				  see pinctrl binding documentation.
+- pinctrl-0: phandle, referring to the SYNC0 signal on configuration node.
+- pinctrl-1: phandle, referring to the SYNC0 signal off configuration node.
+- pinctrl-2: phandle, referring to the LATCH0 signal on configuration node.
+- pinctrl-3: phandle, referring to the LATCH0 signal off configuration node.
 
 
 Must contain children, one for each of the MAC ports.
 Must contain children, one for each of the MAC ports.
 Children must be named ethernet-mii0 and ethernet-mii1.
 Children must be named ethernet-mii0 and ethernet-mii1.
@@ -67,7 +73,7 @@ Optional properties for children:
 
 
 Example (am572x-idk board, dual-emac):
 Example (am572x-idk board, dual-emac):
 ======================================
 ======================================
-	pruss2_eth {
+	pruss2_eth: pruss2_eth {
 		compatible = "ti,am57-prueth";
 		compatible = "ti,am57-prueth";
 		prus = <&pru2_0>, <&pru2_1>;
 		prus = <&pru2_0>, <&pru2_1>;
 		firmware-name = "ti-pruss/am57xx-pru0-prueth-fw.elf",
 		firmware-name = "ti-pruss/am57xx-pru0-prueth-fw.elf",
@@ -100,7 +106,7 @@ Example (am572x-idk board, dual-emac):
 
 
 Example (am572x-idk board, single-emac):
 Example (am572x-idk board, single-emac):
 =======================================
 =======================================
-	pruss2_eth {
+	pruss2_eth: pruss2_eth {
 		compatible = "ti,am57-prueth";
 		compatible = "ti,am57-prueth";
 		prus = <&pru2_0>, <&pru2_1>;
 		prus = <&pru2_0>, <&pru2_1>;
 		firmware-name = "",
 		firmware-name = "",
@@ -120,3 +126,14 @@ Example (am572x-idk board, single-emac):
 			local-mac-address = [00 00 00 00 00 00];
 			local-mac-address = [00 00 00 00 00 00];
 		};
 		};
 	};
 	};
+
+
+Example (am572x-idk board, SYNC/LATCH configurations):
+======================================================
+&pruss2_eth {
+	pinctrl-names = "sync0_off", "sync0_on", "latch0_off", "latch0_on";
+	pinctrl-0 = <&pr2_edc_sync0_off>;
+	pinctrl-1 = <&pr2_edc_sync0_on>;
+	pinctrl-2 = <&pr2_edc_latch0_off>;
+	pinctrl-3 = <&pr2_edc_latch0_on>;
+};

+ 12 - 0
Documentation/devicetree/bindings/net/ti-ptp-bc.txt

@@ -4,6 +4,9 @@ Texas Instruments PTP Boundary Clcok Internal Sync Monitor
 Required properties:
 Required properties:
 - compatible       : Should be
 - compatible       : Should be
                         "ti,am57-bc" for AM57xx SoCs
                         "ti,am57-bc" for AM57xx SoCs
+Optional properties:
+- pps-sel0-gpios	: GPIO specifier, used to select PPS BC mux output
+- pps-sel1-gpios	: GPIO specifier, used to select PPS BC mux output
 
 
 Example:
 Example:
 ========
 ========
@@ -19,3 +22,12 @@ To enable for am572x-idk, in am572x-idk.dts:
 &ptp_bc {
 &ptp_bc {
 	status = "okay";
 	status = "okay";
 };
 };
+
+To enable for am571x-idk-pps, in am572x-idk-pps.dtso:
+
+&ptp_bc {
+	pps-sel0-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
+	pps-sel1-gpios = <&gpio6 7 GPIO_ACTIVE_HIGH>;
+
+	status = "okay";
+};

+ 6 - 5
arch/arm/boot/dts/ti/am571x-idk-pps.dtso

@@ -11,7 +11,8 @@
 
 
 &mac {
 &mac {
 	/* cptr pps1 generator and latch properties */
 	/* cptr pps1 generator and latch properties */
-	timers = <&timer16>, <&timer15>;
+	pps_timer = <&timer16>;
+	latch_timer = <&timer15>;
 	pinctrl-names = "pwm_off", "pwm_on", "ref_off", "ref_on",
 	pinctrl-names = "pwm_off", "pwm_on", "ref_off", "ref_on",
 			"latch_on", "latch_off";
 			"latch_on", "latch_off";
 	pinctrl-0 = <&pps1_timer16_pwm_off>;
 	pinctrl-0 = <&pps1_timer16_pwm_off>;
@@ -50,7 +51,7 @@
 
 
 	pps1_timer16_pwm_off: pps1_timer16_pwm_off {
 	pps1_timer16_pwm_off: pps1_timer16_pwm_off {
 		pinctrl-single,pins = <
 		pinctrl-single,pins = <
-			DRA7XX_CORE_IOPAD(0x36a0, PIN_OUTPUT | MUX_MODE15)
+			DRA7XX_CORE_IOPAD(0x36a0, PIN_OUTPUT_PULLDOWN | MUX_MODE15)
 		>;
 		>;
 	};
 	};
 
 
@@ -62,7 +63,7 @@
 
 
 	pps1_timer16_pwm2_off: pps1_timer16_pwm2_off {
 	pps1_timer16_pwm2_off: pps1_timer16_pwm2_off {
 		pinctrl-single,pins = <
 		pinctrl-single,pins = <
-			DRA7XX_CORE_IOPAD(0x3680, PIN_OUTPUT | MUX_MODE15)
+			DRA7XX_CORE_IOPAD(0x3680, PIN_OUTPUT_PULLDOWN | MUX_MODE15)
 		>;
 		>;
 	};
 	};
 
 
@@ -86,7 +87,7 @@
 
 
 	pr1_edc_sync0_off: pr1_edc_sync0_off {
 	pr1_edc_sync0_off: pr1_edc_sync0_off {
 		pinctrl-single,pins = <
 		pinctrl-single,pins = <
-			DRA7XX_CORE_IOPAD(0x3724, PIN_OUTPUT | MUX_MODE15)
+			DRA7XX_CORE_IOPAD(0x3724, PIN_OUTPUT_PULLDOWN | MUX_MODE15)
 		>;
 		>;
 	};
 	};
 
 
@@ -110,7 +111,7 @@
 
 
 	pr2_edc_sync0_off: pr2_edc_sync0_off {
 	pr2_edc_sync0_off: pr2_edc_sync0_off {
 		pinctrl-single,pins = <
 		pinctrl-single,pins = <
-			DRA7XX_CORE_IOPAD(0x3728, PIN_OUTPUT | MUX_MODE15)
+			DRA7XX_CORE_IOPAD(0x3728, PIN_OUTPUT_PULLDOWN | MUX_MODE15)
 		>;
 		>;
 	};
 	};
 
 

+ 6 - 5
arch/arm/boot/dts/ti/am572x-idk-pps.dtso

@@ -11,7 +11,8 @@
 
 
 &mac {
 &mac {
 	/* cptr pps1 generator and latch properties */
 	/* cptr pps1 generator and latch properties */
-	timers = <&timer16>, <&timer15>;
+	pps_timer = <&timer16>;
+	latch_timer = <&timer15>;
 	pinctrl-names = "pwm_off", "pwm_on", "ref_off", "ref_on",
 	pinctrl-names = "pwm_off", "pwm_on", "ref_off", "ref_on",
 			"latch_on", "latch_off";
 			"latch_on", "latch_off";
 	pinctrl-0 = <&pps1_timer16_pwm_off>;
 	pinctrl-0 = <&pps1_timer16_pwm_off>;
@@ -45,7 +46,7 @@
 
 
 	pps1_timer16_pwm_off: pps1_timer16_pwm_off {
 	pps1_timer16_pwm_off: pps1_timer16_pwm_off {
 		pinctrl-single,pins = <
 		pinctrl-single,pins = <
-			DRA7XX_CORE_IOPAD(0x36a0, PIN_OUTPUT | MUX_MODE15)
+			DRA7XX_CORE_IOPAD(0x36a0, PIN_OUTPUT_PULLDOWN | MUX_MODE15)
 		>;
 		>;
 	};
 	};
 
 
@@ -57,7 +58,7 @@
 
 
 	pps1_timer16_pwm2_off: pps1_timer16_pwm2_off {
 	pps1_timer16_pwm2_off: pps1_timer16_pwm2_off {
 		pinctrl-single,pins = <
 		pinctrl-single,pins = <
-			DRA7XX_CORE_IOPAD(0x3680, PIN_OUTPUT | MUX_MODE15)
+			DRA7XX_CORE_IOPAD(0x3680, PIN_OUTPUT_PULLDOWN | MUX_MODE15)
 		>;
 		>;
 	};
 	};
 
 
@@ -81,7 +82,7 @@
 
 
 	pr2_edc_sync0_off: pr2_edc_sync0_off {
 	pr2_edc_sync0_off: pr2_edc_sync0_off {
 		pinctrl-single,pins = <
 		pinctrl-single,pins = <
-			DRA7XX_CORE_IOPAD(0x35f8, PIN_OUTPUT | MUX_MODE15)
+			DRA7XX_CORE_IOPAD(0x35f8, PIN_OUTPUT_PULLDOWN | MUX_MODE15)
 		>;
 		>;
 	};
 	};
 
 
@@ -105,7 +106,7 @@
 
 
 	pr2_edc_sync1_off: pr2_edc_sync1_off {
 	pr2_edc_sync1_off: pr2_edc_sync1_off {
 		pinctrl-single,pins = <
 		pinctrl-single,pins = <
-			DRA7XX_CORE_IOPAD(0x35fc, PIN_OUTPUT | MUX_MODE15)
+			DRA7XX_CORE_IOPAD(0x35fc, PIN_OUTPUT_PULLDOWN | MUX_MODE15)
 		>;
 		>;
 	};
 	};
 };
 };

+ 6 - 5
arch/arm/boot/dts/ti/am574x-idk-pps.dtso

@@ -12,7 +12,8 @@
 
 
 &mac {
 &mac {
 	/* cptr pps1 generator and latch properties */
 	/* cptr pps1 generator and latch properties */
-	timers = <&timer16>, <&timer15>;
+	pps_timer = <&timer16>;
+	latch_timer = <&timer15>;
 	pinctrl-names = "pwm_off", "pwm_on", "ref_off", "ref_on",
 	pinctrl-names = "pwm_off", "pwm_on", "ref_off", "ref_on",
 			"latch_on", "latch_off";
 			"latch_on", "latch_off";
 	pinctrl-0 = <&pps1_timer16_pwm_off>;
 	pinctrl-0 = <&pps1_timer16_pwm_off>;
@@ -46,7 +47,7 @@
 
 
 	pps1_timer16_pwm_off: pps1_timer16_pwm_off {
 	pps1_timer16_pwm_off: pps1_timer16_pwm_off {
 		pinctrl-single,pins = <
 		pinctrl-single,pins = <
-			DRA7XX_CORE_IOPAD(0x36a0, PIN_OUTPUT | MUX_MODE15)
+			DRA7XX_CORE_IOPAD(0x36a0, PIN_OUTPUT_PULLDOWN | MUX_MODE15)
 		>;
 		>;
 	};
 	};
 
 
@@ -58,7 +59,7 @@
 
 
 	pps1_timer16_pwm2_off: pps1_timer16_pwm2_off {
 	pps1_timer16_pwm2_off: pps1_timer16_pwm2_off {
 		pinctrl-single,pins = <
 		pinctrl-single,pins = <
-			DRA7XX_CORE_IOPAD(0x3680, PIN_OUTPUT | MUX_MODE15)
+			DRA7XX_CORE_IOPAD(0x3680, PIN_OUTPUT_PULLDOWN | MUX_MODE15)
 		>;
 		>;
 	};
 	};
 
 
@@ -82,7 +83,7 @@
 
 
 	pr2_edc_sync0_off: pr2_edc_sync0_off {
 	pr2_edc_sync0_off: pr2_edc_sync0_off {
 		pinctrl-single,pins = <
 		pinctrl-single,pins = <
-			DRA7XX_CORE_IOPAD(0x35f8, PIN_OUTPUT | MUX_MODE15)
+			DRA7XX_CORE_IOPAD(0x35f8, PIN_OUTPUT_PULLDOWN | MUX_MODE15)
 		>;
 		>;
 	};
 	};
 
 
@@ -106,7 +107,7 @@
 
 
 	pr2_edc_sync1_off: pr2_edc_sync1_off {
 	pr2_edc_sync1_off: pr2_edc_sync1_off {
 		pinctrl-single,pins = <
 		pinctrl-single,pins = <
-			DRA7XX_CORE_IOPAD(0x35fc, PIN_OUTPUT | MUX_MODE15)
+			DRA7XX_CORE_IOPAD(0x35fc, PIN_OUTPUT_PULLDOWN | MUX_MODE15)
 		>;
 		>;
 	};
 	};
 };
 };

+ 249 - 144
drivers/net/ethernet/ti/cpts.c

@@ -440,7 +440,8 @@ static int cpts_proc_pps_ts_events(struct cpts *cpts)
 	list_for_each_safe(this, next, &cpts->events) {
 	list_for_each_safe(this, next, &cpts->events) {
 		event = list_entry(this, struct cpts_event, list);
 		event = list_entry(this, struct cpts_event, list);
 		ev = event_type(event);
 		ev = event_type(event);
-		if (ev == CPTS_EV_HW && (cpts_event_port(event) == 4)) {
+		if (ev == CPTS_EV_HW &&
+		    (cpts_event_port(event) == (cpts->pps_hw_index + 1))) {
 			list_del_init(&event->list);
 			list_del_init(&event->list);
 			list_add(&event->list, &cpts->pool);
 			list_add(&event->list, &cpts->pool);
 			/* record the timestamp only */
 			/* record the timestamp only */
@@ -498,9 +499,11 @@ static int cpts_pps_enable(struct cpts *cpts, int on)
 	if (!on)
 	if (!on)
 		return 0;
 		return 0;
 
 
-	spin_lock_bh(&cpts->bc_mux_lock);
-	gpio_set_value(cpts->pps_enable_gpio, 1);
-	spin_unlock_bh(&cpts->bc_mux_lock);
+	if (cpts->pps_enable_gpio >= 0) {
+		spin_lock_bh(&cpts->bc_mux_lock);
+		gpio_set_value(cpts->pps_enable_gpio, 1);
+		spin_unlock_bh(&cpts->bc_mux_lock);
+	}
 
 
 	if (cpts->ref_enable == -1) {
 	if (cpts->ref_enable == -1) {
 		cpts_pps_start(cpts);
 		cpts_pps_start(cpts);
@@ -542,24 +545,31 @@ static int cpts_pps_init(struct cpts *cpts)
 	cpts->ref_enable = -1;
 	cpts->ref_enable = -1;
 	cpts->pps_offset = 0;
 	cpts->pps_offset = 0;
 
 
-	spin_lock_init(&cpts->bc_mux_lock);
+	if (cpts->use_1pps_gen) {
+		spin_lock_init(&cpts->bc_mux_lock);
 
 
 #ifdef CONFIG_OMAP_DM_TIMER
 #ifdef CONFIG_OMAP_DM_TIMER
-	omap_dm_timer_enable(cpts->odt);
-	omap_dm_timer_enable(cpts->odt2);
+		omap_dm_timer_enable(cpts->odt);
 #endif
 #endif
-	cpts_tmr_init(cpts);
 
 
-	kthread_init_delayed_work(&cpts->pps_work, cpts_pps_kworker);
-	cpts->pps_kworker = kthread_create_worker(0, "pps0");
+		kthread_init_delayed_work(&cpts->pps_work, cpts_pps_kworker);
+		cpts->pps_kworker = kthread_create_worker(0, "pps0");
 
 
-	if (IS_ERR(cpts->pps_kworker)) {
-		err = PTR_ERR(cpts->pps_kworker);
-		pr_err("failed to create cpts pps worker %d\n", err);
-		// TBD:add error handling
-		return -1;
+		if (IS_ERR(cpts->pps_kworker)) {
+			err = PTR_ERR(cpts->pps_kworker);
+			pr_err("failed to create cpts pps worker %d\n", err);
+			// TBD:add error handling
+			return -1;
+		}
 	}
 	}
 
 
+#ifdef CONFIG_OMAP_DM_TIMER
+	if (cpts->use_1pps_latch)
+		omap_dm_timer_enable(cpts->odt2);
+#endif
+
+	cpts_tmr_init(cpts);
+
 	return 0;
 	return 0;
 }
 }
 
 
@@ -578,9 +588,11 @@ static void cpts_pps_schedule(struct cpts *cpts)
 			cpts->pps_enable = -1;
 			cpts->pps_enable = -1;
 			pinctrl_select_state(cpts->pins,
 			pinctrl_select_state(cpts->pins,
 					     cpts->pin_state_pwm_off);
 					     cpts->pin_state_pwm_off);
-			spin_lock_bh(&cpts->bc_mux_lock);
-			gpio_set_value(cpts->pps_enable_gpio, 0);
-			spin_unlock_bh(&cpts->bc_mux_lock);
+			if (cpts->pps_enable_gpio >= 0) {
+				spin_lock_bh(&cpts->bc_mux_lock);
+				gpio_set_value(cpts->pps_enable_gpio, 0);
+				spin_unlock_bh(&cpts->bc_mux_lock);
+			}
 		}
 		}
 
 
 		if (!cpts->ref_enable) {
 		if (!cpts->ref_enable) {
@@ -608,7 +620,11 @@ static int cpts_extts_enable(struct cpts *cpts, u32 index, int on)
 	unsigned long flags;
 	unsigned long flags;
 	u32 v;
 	u32 v;
 
 
-	if (index >= cpts->info.n_ext_ts)
+#ifdef CONFIG_TI_1PPS_DM_TIMER
+	if (index >= CPTS_MAX_EXT_TS || index == cpts->pps_hw_index)
+#else
+	if (index >= CPTS_MAX_EXT_TS)
+#endif
 		return -ENXIO;
 		return -ENXIO;
 
 
 	if (((cpts->hw_ts_enable & BIT(index)) >> index) == on)
 	if (((cpts->hw_ts_enable & BIT(index)) >> index) == on)
@@ -621,13 +637,17 @@ static int cpts_extts_enable(struct cpts *cpts, u32 index, int on)
 		v |= BIT(8 + index);
 		v |= BIT(8 + index);
 		cpts->hw_ts_enable |= BIT(index);
 		cpts->hw_ts_enable |= BIT(index);
 #ifdef CONFIG_TI_1PPS_DM_TIMER
 #ifdef CONFIG_TI_1PPS_DM_TIMER
-		pinctrl_select_state(cpts->pins, cpts->pin_state_latch_on);
+		if (cpts->use_1pps_latch)
+			pinctrl_select_state(cpts->pins,
+					     cpts->pin_state_latch_on);
 #endif
 #endif
 	} else {
 	} else {
 		v &= ~BIT(8 + index);
 		v &= ~BIT(8 + index);
 		cpts->hw_ts_enable &= ~BIT(index);
 		cpts->hw_ts_enable &= ~BIT(index);
 #ifdef CONFIG_TI_1PPS_DM_TIMER
 #ifdef CONFIG_TI_1PPS_DM_TIMER
-		pinctrl_select_state(cpts->pins, cpts->pin_state_latch_off);
+		if (cpts->use_1pps_latch)
+			pinctrl_select_state(cpts->pins,
+					     cpts->pin_state_latch_off);
 #endif
 #endif
 	}
 	}
 	cpts_write32(cpts, v, control);
 	cpts_write32(cpts, v, control);
@@ -666,16 +686,22 @@ static int cpts_ptp_enable(struct ptp_clock_info *ptp,
 		return cpts_extts_enable(cpts, rq->extts.index, on);
 		return cpts_extts_enable(cpts, rq->extts.index, on);
 #ifdef CONFIG_TI_1PPS_DM_TIMER
 #ifdef CONFIG_TI_1PPS_DM_TIMER
 	case PTP_CLK_REQ_PPS:
 	case PTP_CLK_REQ_PPS:
-		if (cpts->use_1pps) {
+		if (cpts->use_1pps_gen) {
 			ok = ptp_bc_clock_sync_enable(cpts->bc_clkid, on);
 			ok = ptp_bc_clock_sync_enable(cpts->bc_clkid, on);
 			if (!ok) {
 			if (!ok) {
 				pr_info("cpts error: bc clk sync pps enable denied\n");
 				pr_info("cpts error: bc clk sync pps enable denied\n");
 				return -EBUSY;
 				return -EBUSY;
 			}
 			}
+			return cpts_pps_enable(cpts, on);
+		} else	{
+			return -EOPNOTSUPP;
 		}
 		}
-		return cpts_pps_enable(cpts, on);
+
 	case PTP_CLK_REQ_PEROUT:
 	case PTP_CLK_REQ_PEROUT:
 		/* this enables a pps for external measurement */
 		/* this enables a pps for external measurement */
+		if (!cpts->use_1pps_ref)
+			return -EOPNOTSUPP;
+
 		if (rq->perout.index != 0)
 		if (rq->perout.index != 0)
 			return -EINVAL;
 			return -EINVAL;
 
 
@@ -692,7 +718,7 @@ static int cpts_ptp_enable(struct ptp_clock_info *ptp,
 
 
 		return cpts_ref_enable(cpts, on);
 		return cpts_ref_enable(cpts, on);
 	case PTP_CLK_REQ_PPS_OFFSET:
 	case PTP_CLK_REQ_PPS_OFFSET:
-		if (cpts->use_1pps)
+		if (cpts->use_1pps_gen)
 			cpts->pps_offset = on;
 			cpts->pps_offset = on;
 		return 0;
 		return 0;
 #endif
 #endif
@@ -731,7 +757,7 @@ static const struct ptp_clock_info cpts_info = {
 	.owner		= THIS_MODULE,
 	.owner		= THIS_MODULE,
 	.name		= "CTPS timer",
 	.name		= "CTPS timer",
 	.max_adj	= 1000000,
 	.max_adj	= 1000000,
-	.n_ext_ts	= 0,
+	.n_ext_ts	= CPTS_MAX_EXT_TS,
 	.n_pins		= 0,
 	.n_pins		= 0,
 	.pps		= 0,
 	.pps		= 0,
 	.adjfreq	= cpts_ptp_adjfreq,
 	.adjfreq	= cpts_ptp_adjfreq,
@@ -863,6 +889,13 @@ int cpts_tx_timestamp(struct cpts *cpts, struct sk_buff *skb)
 }
 }
 EXPORT_SYMBOL_GPL(cpts_tx_timestamp);
 EXPORT_SYMBOL_GPL(cpts_tx_timestamp);
 
 
+#ifdef CONFIG_TI_1PPS_DM_TIMER
+static u32 cpts_hw_ts_push_en[4] = {HW1_TS_PUSH_EN,
+				    HW2_TS_PUSH_EN,
+				    HW3_TS_PUSH_EN,
+				    HW4_TS_PUSH_EN};
+#endif
+
 int cpts_register(struct cpts *cpts)
 int cpts_register(struct cpts *cpts)
 {
 {
 	int err, i;
 	int err, i;
@@ -890,14 +923,15 @@ int cpts_register(struct cpts *cpts)
 
 
 	ptp_schedule_worker(cpts->clock, cpts->ov_check_period);
 	ptp_schedule_worker(cpts->clock, cpts->ov_check_period);
 #ifdef CONFIG_TI_1PPS_DM_TIMER
 #ifdef CONFIG_TI_1PPS_DM_TIMER
-	cpts_write32(cpts, cpts_read32(cpts, control) |
-		     HW4_TS_PUSH_EN, control);
-
-	if (cpts->use_1pps) {
+	if (cpts->use_1pps_gen) {
 		cpts->bc_clkid = ptp_bc_clock_register(PTP_BC_CLOCK_TYPE_GMAC);
 		cpts->bc_clkid = ptp_bc_clock_register(PTP_BC_CLOCK_TYPE_GMAC);
 		pr_info("cpts ptp bc clkid %d\n", cpts->bc_clkid);
 		pr_info("cpts ptp bc clkid %d\n", cpts->bc_clkid);
 		ptp_bc_mux_ctrl_register((void *)cpts, &cpts->bc_mux_lock,
 		ptp_bc_mux_ctrl_register((void *)cpts, &cpts->bc_mux_lock,
 					 cpts_bc_mux_ctrl);
 					 cpts_bc_mux_ctrl);
+		cpts_write32(cpts, cpts_read32(cpts, control) |
+			     cpts_hw_ts_push_en[cpts->pps_hw_index],
+			     control);
+
 	}
 	}
 #endif
 #endif
 	return 0;
 	return 0;
@@ -971,46 +1005,32 @@ static void cpts_calc_mult_shift(struct cpts *cpts)
 static int cpts_of_1pps_parse(struct cpts *cpts, struct device_node *node)
 static int cpts_of_1pps_parse(struct cpts *cpts, struct device_node *node)
 {
 {
 	struct device_node *np = NULL;
 	struct device_node *np = NULL;
-	struct device_node *np2 = NULL;
 	int gpio, ret;
 	int gpio, ret;
+	u32 prop;
 
 
-	np = of_parse_phandle(node, "timers", 0);
+	np = of_parse_phandle(node, "pps_timer", 0);
 	if (!np) {
 	if (!np) {
-		dev_err(cpts->dev, "device node lookup for pps timer failed\n");
-		return -ENXIO;
-	}
-
-	np2 = of_parse_phandle(node, "timers", 1);
-	if (!np2) {
-		dev_err(cpts->dev, "device node lookup for pps timer input failed\n");
+		dev_dbg(cpts->dev,
+			"device node lookup for pps timer failed\n");
 		return -ENXIO;
 		return -ENXIO;
 	}
 	}
 
 
-	cpts->pps_tmr_irqn = of_irq_get(np, 0);
-	if (!cpts->pps_tmr_irqn)
-		dev_err(cpts->dev, "cannot get 1pps timer interrupt number\n");
-
-	cpts->pps_latch_irqn = of_irq_get(np2, 0);
-	if (!cpts->pps_latch_irqn)
-		dev_err(cpts->dev, "cannot get 1pps latch interrupt number\n");
-
 #ifdef CONFIG_OMAP_DM_TIMER
 #ifdef CONFIG_OMAP_DM_TIMER
 	cpts->odt = omap_dm_timer_request_by_node(np);
 	cpts->odt = omap_dm_timer_request_by_node(np);
-	cpts->odt2 = omap_dm_timer_request_by_node(np2);
 #endif
 #endif
-	if (!cpts->odt || !cpts->odt2)
+	if (!cpts->odt)
 		return -EPROBE_DEFER;
 		return -EPROBE_DEFER;
 
 
 	if (IS_ERR(cpts->odt)) {
 	if (IS_ERR(cpts->odt)) {
-		dev_err(cpts->dev, "request for 1pps timer failed: %ld\n",
+		dev_err(cpts->dev, "request for 1pps DM timer failed: %ld\n",
 			PTR_ERR(cpts->odt));
 			PTR_ERR(cpts->odt));
 		return PTR_ERR(cpts->odt);
 		return PTR_ERR(cpts->odt);
 	}
 	}
 
 
-	if (IS_ERR(cpts->odt2)) {
-		dev_err(cpts->dev, "request for 1pps timer input failed: %ld\n",
-			PTR_ERR(cpts->odt2));
-		return PTR_ERR(cpts->odt2);
+	cpts->pps_tmr_irqn = of_irq_get(np, 0);
+	if (!cpts->pps_tmr_irqn) {
+		dev_err(cpts->dev, "cannot get 1pps timer interrupt number\n");
+		return -EINVAL;
 	}
 	}
 
 
 	cpts->pins = devm_pinctrl_get(cpts->dev);
 	cpts->pins = devm_pinctrl_get(cpts->dev);
@@ -1034,62 +1054,50 @@ static int cpts_of_1pps_parse(struct cpts *cpts, struct device_node *node)
 		return PTR_ERR(cpts->pin_state_pwm_off);
 		return PTR_ERR(cpts->pin_state_pwm_off);
 	}
 	}
 
 
-	cpts->pin_state_latch_on = pinctrl_lookup_state(cpts->pins,
-							"latch_on");
-	if (IS_ERR(cpts->pin_state_latch_on)) {
-		dev_err(cpts->dev, "lookup for latch_on pin state failed: %ld\n",
-			PTR_ERR(cpts->pin_state_latch_on));
-		return PTR_ERR(cpts->pin_state_latch_on);
-	}
-
-	cpts->pin_state_latch_off = pinctrl_lookup_state(cpts->pins,
-							 "latch_off");
-	if (IS_ERR(cpts->pin_state_latch_off)) {
-		dev_err(cpts->dev, "lookup for latch_off pin state failed: %ld\n",
-			PTR_ERR(cpts->pin_state_latch_off));
-		return PTR_ERR(cpts->pin_state_latch_off);
-	}
-
+	/* The 1PPS enable-gpio signal is only optional and therefore it
+	 * may not be provided by DTB.
+	 */
+	cpts->pps_enable_gpio = -1;
 	gpio = of_get_named_gpio(node, "pps-enable-gpios", 0);
 	gpio = of_get_named_gpio(node, "pps-enable-gpios", 0);
 	if (!gpio_is_valid(gpio)) {
 	if (!gpio_is_valid(gpio)) {
-		dev_err(cpts->dev, "failed to parse pps-enable gpio\n");
-		return gpio;
-	}
+		dev_dbg(cpts->dev, "there is no pps-enable gpio\n");
+	} else {
 
 
-	ret = devm_gpio_request(cpts->dev, gpio, "pps-enable-ctrl");
-	if (ret) {
-		dev_err(cpts->dev, "failed to acquire pps-enable gpio\n");
-		return ret;
+		ret = devm_gpio_request(cpts->dev, gpio, "pps-enable-ctrl");
+		if (ret) {
+			dev_err(cpts->dev,
+				"failed to acquire pps-enable gpio\n");
+			return ret;
+		}
+		cpts->pps_enable_gpio = gpio;
+		gpio_direction_output(gpio, 0);
 	}
 	}
-	cpts->pps_enable_gpio = gpio;
-	gpio_direction_output(gpio, 0);
+
+	if (!of_property_read_u32(node, "cpts_pps_hw_event_index", &prop))
+		cpts->pps_hw_index = prop;
+	else
+		cpts->pps_hw_index = CPTS_PPS_HW_INDEX;
+
+	if (cpts->pps_hw_index > CPTS_PPS_HW_INDEX)
+		cpts->pps_hw_index = CPTS_PPS_HW_INDEX;
+
+	dev_dbg(cpts->dev, "cpts pps hw event index = %d\n",
+		cpts->pps_hw_index);
+
+	cpts->use_1pps_gen = true;
 
 
 	/* The 1PPS reference signal is only optional and therefore the
 	/* The 1PPS reference signal is only optional and therefore the
 	 * corresponding pins may not be provided by DTB.
 	 * corresponding pins may not be provided by DTB.
 	 */
 	 */
 
 
-	gpio = of_get_named_gpio(node, "ref-enable-gpios", 0);
-	if (!gpio_is_valid(gpio)) {
-		cpts->ref_enable_gpio = -1;
+	cpts->pin_state_ref_on = pinctrl_lookup_state(cpts->pins,
+						      "ref_on");
+	if (IS_ERR(cpts->pin_state_ref_on)) {
+		dev_notice(cpts->dev,
+			   "lookup for ref_on pin state failed: %ld\n",
+			   PTR_ERR(cpts->pin_state_ref_on));
+		return PTR_ERR(cpts->pin_state_ref_on);
 	} else {
 	} else {
-		ret = devm_gpio_request(cpts->dev, gpio, "ref-enable-ctrl");
-		if (ret) {
-			dev_err(cpts->dev,
-				"failed to acquire ref-enable gpio\n");
-			devm_gpio_free(cpts->dev, cpts->pps_enable_gpio);
-			return ret;
-		}
-		cpts->ref_enable_gpio = gpio;
-		gpio_direction_output(gpio, 1);
-
-		cpts->pin_state_ref_on = pinctrl_lookup_state(cpts->pins,
-							      "ref_on");
-		if (IS_ERR(cpts->pin_state_ref_on)) {
-			dev_err(cpts->dev,
-				"lookup for ref_on pin state failed: %ld\n",
-				PTR_ERR(cpts->pin_state_ref_on));
-			return PTR_ERR(cpts->pin_state_ref_on);
-		}
 
 
 		cpts->pin_state_ref_off = pinctrl_lookup_state(cpts->pins,
 		cpts->pin_state_ref_off = pinctrl_lookup_state(cpts->pins,
 							       "ref_off");
 							       "ref_off");
@@ -1099,6 +1107,83 @@ static int cpts_of_1pps_parse(struct cpts *cpts, struct device_node *node)
 				PTR_ERR(cpts->pin_state_ref_off));
 				PTR_ERR(cpts->pin_state_ref_off));
 			return PTR_ERR(cpts->pin_state_ref_off);
 			return PTR_ERR(cpts->pin_state_ref_off);
 		}
 		}
+
+		/* The 1PPS ref-enable-gpio signal is only optional and
+		 * therefore it	 may not be provided by DTB.
+		 */
+		cpts->ref_enable_gpio = -1;
+		gpio = of_get_named_gpio(node, "ref-enable-gpios", 0);
+		if (!gpio_is_valid(gpio)) {
+			dev_dbg(cpts->dev,
+				"there is no ref-enable gpio\n");
+		} else {
+			ret = devm_gpio_request(cpts->dev, gpio,
+						"ref-enable-ctrl");
+			if (ret) {
+				dev_err(cpts->dev,
+					"failed to acquire ref-enable gpio\n");
+				devm_gpio_free(cpts->dev,
+					       cpts->pps_enable_gpio);
+				return ret;
+			}
+			cpts->ref_enable_gpio = gpio;
+			gpio_direction_output(gpio, 1);
+		}
+		cpts->use_1pps_ref = true;
+	}
+
+	return 0;
+}
+
+static int cpts_of_1pps_latch_parse(struct cpts *cpts, struct device_node *node)
+{
+	struct device_node *np2 = NULL;
+
+	np2 = of_parse_phandle(node, "latch_timer", 0);
+	if (!np2) {
+		dev_dbg(cpts->dev,
+			"device node lookup for latch timer input failed\n");
+		return -ENXIO;
+	}
+
+#ifdef CONFIG_OMAP_DM_TIMER
+	cpts->odt2 = omap_dm_timer_request_by_node(np2);
+#endif
+	if (!cpts->odt2)
+		return -EPROBE_DEFER;
+
+	if (IS_ERR(cpts->odt2)) {
+		dev_err(cpts->dev,
+			"request for 1pps latch timer input failed: %ld\n",
+			PTR_ERR(cpts->odt2));
+		return PTR_ERR(cpts->odt2);
+	}
+
+	cpts->pps_latch_irqn = of_irq_get(np2, 0);
+	if (!cpts->pps_latch_irqn)
+		dev_err(cpts->dev, "cannot get 1pps latch interrupt number\n");
+
+	cpts->pins = devm_pinctrl_get(cpts->dev);
+	if (IS_ERR(cpts->pins)) {
+		dev_err(cpts->dev, "request for 1pps pins failed: %ld\n",
+			PTR_ERR(cpts->pins));
+		return PTR_ERR(cpts->pins);
+	}
+
+	cpts->pin_state_latch_on = pinctrl_lookup_state(cpts->pins,
+							"latch_on");
+	if (IS_ERR(cpts->pin_state_latch_on)) {
+		dev_err(cpts->dev, "lookup for latch_on pin state failed: %ld\n",
+			PTR_ERR(cpts->pin_state_latch_on));
+		return PTR_ERR(cpts->pin_state_latch_on);
+	}
+
+	cpts->pin_state_latch_off = pinctrl_lookup_state(cpts->pins,
+							 "latch_off");
+	if (IS_ERR(cpts->pin_state_latch_off)) {
+		dev_err(cpts->dev, "lookup for latch_off pin state failed: %ld\n",
+			PTR_ERR(cpts->pin_state_latch_off));
+		return PTR_ERR(cpts->pin_state_latch_off);
 	}
 	}
 
 
 	return 0;
 	return 0;
@@ -1138,7 +1223,11 @@ static int cpts_of_parse(struct cpts *cpts, struct device_node *node)
 	if (ret == -EPROBE_DEFER)
 	if (ret == -EPROBE_DEFER)
 		return ret;
 		return ret;
 
 
-	cpts->use_1pps = (ret == 0);
+	ret = cpts_of_1pps_latch_parse(cpts, node);
+	if (ret == -EPROBE_DEFER)
+		return ret;
+
+	cpts->use_1pps_latch = (ret == 0);
 #endif
 #endif
 
 
 	return 0;
 	return 0;
@@ -1213,7 +1302,7 @@ struct cpts *cpts_create(struct device *dev, void __iomem *regs,
 		}
 		}
 	}
 	}
 
 
-	if (cpts->use_1pps) {
+	if (cpts->use_1pps_gen || cpts->use_1pps_latch) {
 		ret = cpts_pps_init(cpts);
 		ret = cpts_pps_init(cpts);
 
 
 		if (ret < 0) {
 		if (ret < 0) {
@@ -1223,9 +1312,10 @@ struct cpts *cpts_create(struct device *dev, void __iomem *regs,
 		}
 		}
 
 
 		/* Enable 1PPS related features	*/
 		/* Enable 1PPS related features	*/
-		cpts->info.pps		= 1;
-		cpts->info.n_ext_ts	= CPTS_MAX_LATCH;
-		cpts->info.n_per_out	= (cpts->ref_enable_gpio >= 0) ? 1 : 0;
+		cpts->info.pps		= (cpts->use_1pps_gen) ? 1 : 0;
+		cpts->info.n_ext_ts	= (cpts->use_1pps_gen) ?
+					  CPTS_MAX_EXT_TS - 1 : CPTS_MAX_EXT_TS;
+		cpts->info.n_per_out	= (cpts->use_1pps_ref) ? 1 : 0;
 	}
 	}
 #endif
 #endif
 
 
@@ -1281,6 +1371,9 @@ static void cpts_bc_mux_ctrl(void *ctx, int enable)
 	struct cpts *cpts = (struct cpts *)ctx;
 	struct cpts *cpts = (struct cpts *)ctx;
 	static int state;
 	static int state;
 
 
+	if (cpts->pps_enable_gpio < 0)
+		return;
+
 	if (enable) {
 	if (enable) {
 		if (!state)
 		if (!state)
 			gpio_set_value(cpts->pps_enable_gpio, 0);
 			gpio_set_value(cpts->pps_enable_gpio, 0);
@@ -1369,46 +1462,52 @@ static void cpts_tmr_init(struct cpts *cpts)
 	if (!cpts)
 	if (!cpts)
 		return;
 		return;
 
 
-	parent = clk_get(&cpts->odt->pdev->dev, "abe_giclk_div");
-	if (IS_ERR(parent)) {
-		pr_err("%s: %s not found\n", __func__, "abe_giclk_div");
-		return;
-	}
+	if (cpts->use_1pps_gen)	{
+		parent = clk_get(&cpts->odt->pdev->dev, "abe_giclk_div");
+		if (IS_ERR(parent)) {
+			pr_err("%s: %s not found\n", __func__, "abe_giclk_div");
+			return;
+		}
 
 
-	ret = clk_set_parent(cpts->odt->fclk, parent);
-	if (ret < 0)
-		pr_err("%s: failed to set %s as parent\n", __func__,
-		       "abe_giclk_div");
+		ret = clk_set_parent(cpts->odt->fclk, parent);
+		if (ret < 0)
+			pr_err("%s: failed to set %s as parent\n", __func__,
+			       "abe_giclk_div");
 
 
-	parent = clk_get(&cpts->odt2->pdev->dev, "abe_giclk_div");
-	if (IS_ERR(parent)) {
-		pr_err("%s: %s not found\n", __func__, "abe_giclk_div");
-		return;
-	}
+		/* initialize timer16 for 1pps generator */
+		cpts_tmr_reinit(cpts);
 
 
-	ret = clk_set_parent(cpts->odt2->fclk, parent);
-	if (ret < 0)
-		pr_err("%s: failed to set %s as parent\n", __func__,
-		       "abe_giclk_div");
+		writel_relaxed(OMAP_TIMER_INT_OVERFLOW, cpts->odt->irq_ena);
+		__omap_dm_timer_write(cpts->odt, OMAP_TIMER_WAKEUP_EN_REG,
+				      OMAP_TIMER_INT_OVERFLOW, 0);
 
 
-	/* initialize timer16 for 1pps generator */
-	cpts_tmr_reinit(cpts);
+		pinctrl_select_state(cpts->pins, cpts->pin_state_pwm_off);
+		if (cpts->use_1pps_ref)
+			pinctrl_select_state(cpts->pins,
+					     cpts->pin_state_ref_off);
+	}
 
 
-	/* initialize timer15 for 1pps latch */
-	cpts_latch_tmr_init(cpts);
+	if (cpts->use_1pps_latch) {
+		parent = clk_get(&cpts->odt2->pdev->dev, "abe_giclk_div");
+		if (IS_ERR(parent)) {
+			pr_err("%s: %s not found\n", __func__, "abe_giclk_div");
+			return;
+		}
 
 
-	writel_relaxed(OMAP_TIMER_INT_OVERFLOW, cpts->odt->irq_ena);
-	__omap_dm_timer_write(cpts->odt, OMAP_TIMER_WAKEUP_EN_REG,
-			      OMAP_TIMER_INT_OVERFLOW, 0);
+		ret = clk_set_parent(cpts->odt2->fclk, parent);
+		if (ret < 0)
+			pr_err("%s: failed to set %s as parent\n", __func__,
+			       "abe_giclk_div");
 
 
-	writel_relaxed(OMAP_TIMER_INT_CAPTURE, cpts->odt2->irq_ena);
-	__omap_dm_timer_write(cpts->odt2, OMAP_TIMER_WAKEUP_EN_REG,
-			      OMAP_TIMER_INT_CAPTURE, 0);
+		/* initialize timer15 for 1pps latch */
+		cpts_latch_tmr_init(cpts);
 
 
-	pinctrl_select_state(cpts->pins, cpts->pin_state_pwm_off);
-	if (cpts->ref_enable_gpio >= 0)
-		pinctrl_select_state(cpts->pins, cpts->pin_state_ref_off);
-	pinctrl_select_state(cpts->pins, cpts->pin_state_latch_off);
+		writel_relaxed(OMAP_TIMER_INT_CAPTURE, cpts->odt2->irq_ena);
+		__omap_dm_timer_write(cpts->odt2, OMAP_TIMER_WAKEUP_EN_REG,
+				      OMAP_TIMER_INT_CAPTURE, 0);
+
+		pinctrl_select_state(cpts->pins, cpts->pin_state_latch_off);
+	}
 }
 }
 
 
 static inline void cpts_turn_on_off_1pps_output(struct cpts *cpts, u64 ts)
 static inline void cpts_turn_on_off_1pps_output(struct cpts *cpts, u64 ts)
@@ -1417,15 +1516,18 @@ static inline void cpts_turn_on_off_1pps_output(struct cpts *cpts, u64 ts)
 		if (cpts->pps_enable == 1) {
 		if (cpts->pps_enable == 1) {
 			pinctrl_select_state(cpts->pins,
 			pinctrl_select_state(cpts->pins,
 					     cpts->pin_state_pwm_on);
 					     cpts->pin_state_pwm_on);
-			spin_lock_bh(&cpts->bc_mux_lock);
-			gpio_set_value(cpts->pps_enable_gpio, 0);
-			spin_unlock_bh(&cpts->bc_mux_lock);
+			if (cpts->pps_enable_gpio >= 0) {
+				spin_lock_bh(&cpts->bc_mux_lock);
+				gpio_set_value(cpts->pps_enable_gpio, 0);
+				spin_unlock_bh(&cpts->bc_mux_lock);
+			}
 		}
 		}
 
 
 		if (cpts->ref_enable == 1) {
 		if (cpts->ref_enable == 1) {
 			pinctrl_select_state(cpts->pins,
 			pinctrl_select_state(cpts->pins,
 					     cpts->pin_state_ref_on);
 					     cpts->pin_state_ref_on);
-			gpio_set_value(cpts->ref_enable_gpio, 0);
+			if (cpts->ref_enable_gpio >= 0)
+				gpio_set_value(cpts->ref_enable_gpio, 0);
 		}
 		}
 
 
 		pr_debug("1pps on at %llu\n", ts);
 		pr_debug("1pps on at %llu\n", ts);
@@ -1433,15 +1535,18 @@ static inline void cpts_turn_on_off_1pps_output(struct cpts *cpts, u64 ts)
 		if (cpts->pps_enable == 1) {
 		if (cpts->pps_enable == 1) {
 			pinctrl_select_state(cpts->pins,
 			pinctrl_select_state(cpts->pins,
 					     cpts->pin_state_pwm_off);
 					     cpts->pin_state_pwm_off);
-			spin_lock_bh(&cpts->bc_mux_lock);
-			gpio_set_value(cpts->pps_enable_gpio, 1);
-			spin_unlock_bh(&cpts->bc_mux_lock);
+			if (cpts->pps_enable_gpio >= 0) {
+				spin_lock_bh(&cpts->bc_mux_lock);
+				gpio_set_value(cpts->pps_enable_gpio, 1);
+				spin_unlock_bh(&cpts->bc_mux_lock);
+			}
 		}
 		}
 
 
 		if (cpts->ref_enable == 1) {
 		if (cpts->ref_enable == 1) {
 			pinctrl_select_state(cpts->pins,
 			pinctrl_select_state(cpts->pins,
 					     cpts->pin_state_ref_off);
 					     cpts->pin_state_ref_off);
-			gpio_set_value(cpts->ref_enable_gpio, 1);
+			if (cpts->ref_enable_gpio >= 0)
+				gpio_set_value(cpts->ref_enable_gpio, 1);
 		}
 		}
 	}
 	}
 }
 }

+ 6 - 4
drivers/net/ethernet/ti/cpts.h

@@ -114,9 +114,8 @@ enum {
 #define CPTS_EVENT_RX_TX_TIMEOUT 20 /* ms */
 #define CPTS_EVENT_RX_TX_TIMEOUT 20 /* ms */
 #define CPTS_EVENT_HWSTAMP_TIMEOUT 200 /* ms */
 #define CPTS_EVENT_HWSTAMP_TIMEOUT 200 /* ms */
 
 
-#ifdef CONFIG_TI_1PPS_DM_TIMER
-#define CPTS_MAX_LATCH	3
-#endif
+#define CPTS_MAX_EXT_TS 4
+#define CPTS_PPS_HW_INDEX 3
 
 
 struct cpts_event {
 struct cpts_event {
 	struct list_head list;
 	struct list_head list;
@@ -152,8 +151,11 @@ struct cpts {
 	u32 caps;
 	u32 caps;
 
 
 #ifdef CONFIG_TI_1PPS_DM_TIMER
 #ifdef CONFIG_TI_1PPS_DM_TIMER
-	u8 use_1pps;
+	u8 use_1pps_gen;
+	u8 use_1pps_latch;
+	u8 use_1pps_ref;
 	u8 pps_latch_receive;
 	u8 pps_latch_receive;
+	int pps_hw_index;
 	int pps_enable;
 	int pps_enable;
 	int pps_state;
 	int pps_state;
 	int pps_latch_state;
 	int pps_latch_state;

+ 17 - 6
drivers/net/ethernet/ti/ptp_bc.c

@@ -53,6 +53,10 @@ static void ptp_bc_free_clk_id(int clkid)
 
 
 static void ptp_bc_clock_pps_mux_reset(void)
 static void ptp_bc_clock_pps_mux_reset(void)
 {
 {
+	if (bc_clk_pps_mux_sel0_gpio < 0 ||
+	    bc_clk_pps_mux_sel1_gpio < 0)
+		return;
+
 	if (bc_mux_ctrl_handler) {
 	if (bc_mux_ctrl_handler) {
 		spin_lock_bh(bc_mux_lock);
 		spin_lock_bh(bc_mux_lock);
 		bc_mux_ctrl_handler(bc_mux_ctrl_ctx, false);
 		bc_mux_ctrl_handler(bc_mux_ctrl_ctx, false);
@@ -74,6 +78,10 @@ static void ptp_bc_clock_pps_mux_sel(int clkid)
 		return;
 		return;
 	}
 	}
 
 
+	if (bc_clk_pps_mux_sel0_gpio < 0 ||
+	    bc_clk_pps_mux_sel1_gpio < 0)
+		return;
+
 	if (bc_mux_ctrl_handler) {
 	if (bc_mux_ctrl_handler) {
 		spin_lock_bh(bc_mux_lock);
 		spin_lock_bh(bc_mux_lock);
 		bc_mux_ctrl_handler(bc_mux_ctrl_ctx, false);
 		bc_mux_ctrl_handler(bc_mux_ctrl_ctx, false);
@@ -207,14 +215,18 @@ EXPORT_SYMBOL_GPL(ptp_bc_mux_ctrl_register);
 static int ptp_bc_probe(struct platform_device *pdev)
 static int ptp_bc_probe(struct platform_device *pdev)
 {
 {
 	struct device_node *np = pdev->dev.of_node;
 	struct device_node *np = pdev->dev.of_node;
-	int ret, gpio;
+	int ret = 0, gpio;
 
 
 	spin_lock_init(&bc_sync_lock);
 	spin_lock_init(&bc_sync_lock);
 	bc_clk_sync_enabled = 0;
 	bc_clk_sync_enabled = 0;
 	bc_clocks_registered = 0;
 	bc_clocks_registered = 0;
+	bc_clk_pps_mux_sel0_gpio = -1;
+	bc_clk_pps_mux_sel1_gpio = -1;
+	ptp_bc_initialized  = true;
+
 	gpio = of_get_named_gpio(np, "pps-sel0-gpios", 0);
 	gpio = of_get_named_gpio(np, "pps-sel0-gpios", 0);
-	if (!gpio_is_valid(bc_clk_pps_mux_sel0_gpio)) {
-		dev_err(&pdev->dev, "failed to parse pps-sel0 gpio\n");
+	if (!gpio_is_valid(gpio)) {
+		dev_dbg(&pdev->dev, "failed to parse pps-sel0 gpio\n");
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
@@ -227,8 +239,8 @@ static int ptp_bc_probe(struct platform_device *pdev)
 	bc_clk_pps_mux_sel0_gpio = gpio;
 	bc_clk_pps_mux_sel0_gpio = gpio;
 
 
 	gpio = of_get_named_gpio(np, "pps-sel1-gpios", 0);
 	gpio = of_get_named_gpio(np, "pps-sel1-gpios", 0);
-	if (!gpio_is_valid(bc_clk_pps_mux_sel1_gpio)) {
-		dev_err(&pdev->dev, "failed to parse pps-sel1 gpio\n");
+	if (!gpio_is_valid(gpio)) {
+		dev_dbg(&pdev->dev, "failed to parse pps-sel1 gpio\n");
 		devm_gpio_free(&pdev->dev, bc_clk_pps_mux_sel0_gpio);
 		devm_gpio_free(&pdev->dev, bc_clk_pps_mux_sel0_gpio);
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
@@ -242,7 +254,6 @@ static int ptp_bc_probe(struct platform_device *pdev)
 	gpio_direction_output(gpio, 0);
 	gpio_direction_output(gpio, 0);
 	bc_clk_pps_mux_sel1_gpio = gpio;
 	bc_clk_pps_mux_sel1_gpio = gpio;
 
 
-	ptp_bc_initialized  = true;
 	return 0;
 	return 0;
 }
 }