* [PATCH v2 0/2] dp83640: Get pin and master/slave configuration from DT
@ 2014-02-11 15:29 Stefan Sørensen
2014-02-11 15:29 ` [PATCH v2 1/2] dp83640: Support a configurable number of periodic outputs Stefan Sørensen
2014-02-11 15:29 ` [PATCH v2 2/2] dp83640: Get pin and master/slave configuration from DT Stefan Sørensen
0 siblings, 2 replies; 7+ messages in thread
From: Stefan Sørensen @ 2014-02-11 15:29 UTC (permalink / raw)
To: richardcochran, grant.likely, robh+dt, mark.rutland, netdev,
linux-kernel, devicetree
Cc: Stefan Sørensen
This patch series add DT configuration to the DP83640 PHY driver and makes
the configuration of periodic output pins dynamic.
Changes since v1:
- Add bindings documentation
- Keep module parameters
- Rename gpio->pin
- Split patch into DT part and dynamic periodic output support
Stefan
Stefan Sørensen (2):
dp83640: Support a configurable number of periodic outputs
dp83640: Get pin and master/slave configuration from DT
Documentation/devicetree/bindings/net/dp83640.txt | 29 +++
drivers/net/phy/dp83640.c | 205 +++++++++++++++-------
2 files changed, 175 insertions(+), 59 deletions(-)
create mode 100644 Documentation/devicetree/bindings/net/dp83640.txt
--
1.8.5.3
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 1/2] dp83640: Support a configurable number of periodic outputs
2014-02-11 15:29 [PATCH v2 0/2] dp83640: Get pin and master/slave configuration from DT Stefan Sørensen
@ 2014-02-11 15:29 ` Stefan Sørensen
2014-02-11 20:09 ` Richard Cochran
2014-02-11 15:29 ` [PATCH v2 2/2] dp83640: Get pin and master/slave configuration from DT Stefan Sørensen
1 sibling, 1 reply; 7+ messages in thread
From: Stefan Sørensen @ 2014-02-11 15:29 UTC (permalink / raw)
To: richardcochran, grant.likely, robh+dt, mark.rutland, netdev,
linux-kernel, devicetree
Cc: Stefan Sørensen
The driver is currently limited to a single periodic output. This patch makes
the number of peridodic output dynamic by dropping the gpio_tab module
parameter and adding calibrate_pin, perout_pins, and extts_pins parameters.
Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
---
drivers/net/phy/dp83640.c | 75 ++++++++++++++++++++---------------------------
1 file changed, 32 insertions(+), 43 deletions(-)
diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c
index 547725f..d4fe95d 100644
--- a/drivers/net/phy/dp83640.c
+++ b/drivers/net/phy/dp83640.c
@@ -38,15 +38,11 @@
#define LAYER4 0x02
#define LAYER2 0x01
#define MAX_RXTS 64
-#define N_EXT_TS 6
+#define N_EXT 8
#define PSF_PTPVER 2
#define PSF_EVNT 0x4000
#define PSF_RX 0x2000
#define PSF_TX 0x1000
-#define EXT_EVENT 1
-#define CAL_EVENT 7
-#define CAL_TRIGGER 7
-#define PER_TRIGGER 6
#define MII_DP83640_MICR 0x11
#define MII_DP83640_MISR 0x12
@@ -146,32 +142,24 @@ struct dp83640_clock {
struct ptp_clock *ptp_clock;
};
-/* globals */
-
-enum {
- CALIBRATE_GPIO,
- PEROUT_GPIO,
- EXTTS0_GPIO,
- EXTTS1_GPIO,
- EXTTS2_GPIO,
- EXTTS3_GPIO,
- EXTTS4_GPIO,
- EXTTS5_GPIO,
- GPIO_TABLE_SIZE
-};
static int chosen_phy = -1;
-static ushort gpio_tab[GPIO_TABLE_SIZE] = {
- 1, 2, 3, 4, 8, 9, 10, 11
-};
+static int calibrate_pin = 1;
+static int perout_pins[N_EXT] = {2};
+static int n_per_out = 1;
+static int extts_pins[N_EXT] = {3, 4, 8, 9, 10, 11};
+static int n_ext_ts = 6;
module_param(chosen_phy, int, 0444);
-module_param_array(gpio_tab, ushort, NULL, 0444);
+module_param(calibrate_pin, int, 0444);
+module_param_array(perout_pins, int, &n_per_out, 0444);
+module_param_array(extts_pins, int, &n_ext_ts, 0444);
MODULE_PARM_DESC(chosen_phy, \
"The address of the PHY to use for the ancillary clock features");
-MODULE_PARM_DESC(gpio_tab, \
- "Which GPIO line to use for which purpose: cal,perout,extts1,...,extts6");
+MODULE_PARM_DESC(calibrate_pin, "Which pin to use for calibration");
+MODULE_PARM_DESC(perout_pins, "Which pins to use for periodic output");
+MODULE_PARM_DESC(extts_pins, "Which pins to use for external timestamping");
/* a list of clocks and a mutex to protect it */
static LIST_HEAD(phyter_clocks);
@@ -267,15 +255,16 @@ static u64 phy2txts(struct phy_txts *p)
}
static void periodic_output(struct dp83640_clock *clock,
- struct ptp_clock_request *clkreq, bool on)
+ struct ptp_clock_request *clkreq, int index,
+ bool on)
{
struct dp83640_private *dp83640 = clock->chosen;
struct phy_device *phydev = dp83640->phydev;
u32 sec, nsec, period;
u16 gpio, ptp_trig, trigger, val;
- gpio = on ? gpio_tab[PEROUT_GPIO] : 0;
- trigger = PER_TRIGGER;
+ gpio = on ? perout_pins[index] : 0;
+ trigger = n_ext_ts + index;
ptp_trig = TRIG_WR |
(trigger & TRIG_CSEL_MASK) << TRIG_CSEL_SHIFT |
@@ -430,12 +419,12 @@ static int ptp_dp83640_enable(struct ptp_clock_info *ptp,
switch (rq->type) {
case PTP_CLK_REQ_EXTTS:
index = rq->extts.index;
- if (index < 0 || index >= N_EXT_TS)
+ if (index < 0 || index >= n_ext_ts)
return -EINVAL;
- event_num = EXT_EVENT + index;
+ event_num = index;
evnt = EVNT_WR | (event_num & EVNT_SEL_MASK) << EVNT_SEL_SHIFT;
if (on) {
- gpio_num = gpio_tab[EXTTS0_GPIO + index];
+ gpio_num = extts_pins[index];
evnt |= (gpio_num & EVNT_GPIO_MASK) << EVNT_GPIO_SHIFT;
evnt |= EVNT_RISE;
}
@@ -443,9 +432,10 @@ static int ptp_dp83640_enable(struct ptp_clock_info *ptp,
return 0;
case PTP_CLK_REQ_PEROUT:
- if (rq->perout.index != 0)
+ index = rq->perout.index;
+ if (index < 0 || index >= n_per_out)
return -EINVAL;
- periodic_output(clock, rq, on);
+ periodic_output(clock, rq, index, on);
return 0;
default:
@@ -538,10 +528,9 @@ static void recalibrate(struct dp83640_clock *clock)
struct list_head *this;
struct dp83640_private *tmp;
struct phy_device *master = clock->chosen->phydev;
- u16 cal_gpio, cfg0, evnt, ptp_trig, trigger, val;
+ u16 cfg0, evnt, ptp_trig, trigger, val;
- trigger = CAL_TRIGGER;
- cal_gpio = gpio_tab[CALIBRATE_GPIO];
+ trigger = n_ext_ts + n_per_out;
mutex_lock(&clock->extreg_lock);
@@ -564,8 +553,8 @@ static void recalibrate(struct dp83640_clock *clock)
* enable an event timestamp
*/
evnt = EVNT_WR | EVNT_RISE | EVNT_SINGLE;
- evnt |= (CAL_EVENT & EVNT_SEL_MASK) << EVNT_SEL_SHIFT;
- evnt |= (cal_gpio & EVNT_GPIO_MASK) << EVNT_GPIO_SHIFT;
+ evnt |= (trigger & EVNT_SEL_MASK) << EVNT_SEL_SHIFT;
+ evnt |= (calibrate_pin & EVNT_GPIO_MASK) << EVNT_GPIO_SHIFT;
list_for_each(this, &clock->phylist) {
tmp = list_entry(this, struct dp83640_private, list);
@@ -578,7 +567,7 @@ static void recalibrate(struct dp83640_clock *clock)
*/
ptp_trig = TRIG_WR | TRIG_IF_LATE | TRIG_PULSE;
ptp_trig |= (trigger & TRIG_CSEL_MASK) << TRIG_CSEL_SHIFT;
- ptp_trig |= (cal_gpio & TRIG_GPIO_MASK) << TRIG_GPIO_SHIFT;
+ ptp_trig |= (calibrate_pin & TRIG_GPIO_MASK) << TRIG_GPIO_SHIFT;
ext_write(0, master, PAGE5, PTP_TRIG, ptp_trig);
/* load trigger */
@@ -642,7 +631,7 @@ static void recalibrate(struct dp83640_clock *clock)
static inline u16 exts_chan_to_edata(int ch)
{
- return 1 << ((ch + EXT_EVENT) * 2);
+ return 1 << ((ch) * 2);
}
static int decode_evnt(struct dp83640_private *dp83640,
@@ -676,14 +665,14 @@ static int decode_evnt(struct dp83640_private *dp83640,
parsed = words + 2;
} else {
parsed = words + 1;
- i = ((ests >> EVNT_NUM_SHIFT) & EVNT_NUM_MASK) - EXT_EVENT;
+ i = ((ests >> EVNT_NUM_SHIFT) & EVNT_NUM_MASK);
ext_status = exts_chan_to_edata(i);
}
event.type = PTP_CLOCK_EXTTS;
event.timestamp = phy2txts(&dp83640->edata);
- for (i = 0; i < N_EXT_TS; i++) {
+ for (i = 0; i < n_ext_ts; i++) {
if (ext_status & exts_chan_to_edata(i)) {
event.index = i;
ptp_clock_event(dp83640->clock->ptp_clock, &event);
@@ -889,8 +878,8 @@ static void dp83640_clock_init(struct dp83640_clock *clock, struct mii_bus *bus)
sprintf(clock->caps.name, "dp83640 timer");
clock->caps.max_adj = 1953124;
clock->caps.n_alarm = 0;
- clock->caps.n_ext_ts = N_EXT_TS;
- clock->caps.n_per_out = 1;
+ clock->caps.n_ext_ts = n_ext_ts;
+ clock->caps.n_per_out = n_per_out;
clock->caps.pps = 0;
clock->caps.adjfreq = ptp_dp83640_adjfreq;
clock->caps.adjtime = ptp_dp83640_adjtime;
--
1.8.5.3
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v2 2/2] dp83640: Get pin and master/slave configuration from DT
2014-02-11 15:29 [PATCH v2 0/2] dp83640: Get pin and master/slave configuration from DT Stefan Sørensen
2014-02-11 15:29 ` [PATCH v2 1/2] dp83640: Support a configurable number of periodic outputs Stefan Sørensen
@ 2014-02-11 15:29 ` Stefan Sørensen
2014-02-11 20:19 ` Richard Cochran
1 sibling, 1 reply; 7+ messages in thread
From: Stefan Sørensen @ 2014-02-11 15:29 UTC (permalink / raw)
To: richardcochran, grant.likely, robh+dt, mark.rutland, netdev,
linux-kernel, devicetree
Cc: Stefan Sørensen
This patch adds configuration of the periodic output and external timestamp
pins available on the dp83640 family of PHYs. It also configures the
master/slave relationship in a group of PHYs on the same MDIO bus and the pins
used for clock calibration in the group.
The configuration is retrieved from DT through the properties
dp83640,slave
dp83640,calibrate-pin
dp83640,perout-pins
dp83640,extts-pins
The configuration module parameters are retained as fallback for the non-DT
case.
Since the pin configuration is now stored for each clock device, groups of
devices on different mdio busses can now have different pin configurations.
Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
---
Documentation/devicetree/bindings/net/dp83640.txt | 29 +++++
drivers/net/phy/dp83640.c | 152 ++++++++++++++++++----
2 files changed, 154 insertions(+), 27 deletions(-)
create mode 100644 Documentation/devicetree/bindings/net/dp83640.txt
diff --git a/Documentation/devicetree/bindings/net/dp83640.txt b/Documentation/devicetree/bindings/net/dp83640.txt
new file mode 100644
index 0000000..b9a57c0
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/dp83640.txt
@@ -0,0 +1,29 @@
+Required properties for the National DP83640 ethernet phy:
+
+- compatible : Must contain "national,dp83640"
+
+Optional properties:
+
+- dp83640,slave: If present, this phy will be slave to another dp83640
+ on the same mdio bus.
+- dp83640,perout-pins : List of the pin pins used for periodic output
+ triggers.
+- dp83640,extts-pins : List of the pin pins used for external event
+ timestamping.
+- dp83640,calibrate-pin : The pin used for master/slave calibration.
+
+Example:
+
+ ethernet-phy@1 {
+ compatible = "national,dp83640", "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ dp83640,perout-pins = <2>;
+ dp83640,extts-pins = <3 4 8 9 10 11>;
+ dp83640,calibrate-pin = <1>;
+ };
+
+ ethernet-phy@2 {
+ compatible = "national,dp83640", "ethernet-phy-ieee802.3-c22";
+ reg = <2>;
+ dp83640,slave;
+ };
diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c
index d4fe95d..a9bd553 100644
--- a/drivers/net/phy/dp83640.c
+++ b/drivers/net/phy/dp83640.c
@@ -30,6 +30,7 @@
#include <linux/phy.h>
#include <linux/ptp_classify.h>
#include <linux/ptp_clock_kernel.h>
+#include <linux/of_device.h>
#include "dp83640_reg.h"
@@ -119,6 +120,8 @@ struct dp83640_private {
/* queues of incoming and outgoing packets */
struct sk_buff_head rx_queue;
struct sk_buff_head tx_queue;
+ /* is this phyter a slave */
+ bool slave;
};
struct dp83640_clock {
@@ -140,6 +143,7 @@ struct dp83640_clock {
struct list_head phylist;
/* reference to our PTP hardware clock */
struct ptp_clock *ptp_clock;
+ u32 perout_pins[N_EXT], extts_pins[N_EXT], calibrate_pin;
};
@@ -263,8 +267,8 @@ static void periodic_output(struct dp83640_clock *clock,
u32 sec, nsec, period;
u16 gpio, ptp_trig, trigger, val;
- gpio = on ? perout_pins[index] : 0;
- trigger = n_ext_ts + index;
+ gpio = on ? clock->perout_pins[index] : 0;
+ trigger = clock->caps.n_ext_ts + index;
ptp_trig = TRIG_WR |
(trigger & TRIG_CSEL_MASK) << TRIG_CSEL_SHIFT |
@@ -419,12 +423,12 @@ static int ptp_dp83640_enable(struct ptp_clock_info *ptp,
switch (rq->type) {
case PTP_CLK_REQ_EXTTS:
index = rq->extts.index;
- if (index < 0 || index >= n_ext_ts)
+ if (index < 0 || index >= clock->caps.n_ext_ts)
return -EINVAL;
event_num = index;
evnt = EVNT_WR | (event_num & EVNT_SEL_MASK) << EVNT_SEL_SHIFT;
if (on) {
- gpio_num = extts_pins[index];
+ gpio_num = clock->extts_pins[index];
evnt |= (gpio_num & EVNT_GPIO_MASK) << EVNT_GPIO_SHIFT;
evnt |= EVNT_RISE;
}
@@ -433,7 +437,7 @@ static int ptp_dp83640_enable(struct ptp_clock_info *ptp,
case PTP_CLK_REQ_PEROUT:
index = rq->perout.index;
- if (index < 0 || index >= n_per_out)
+ if (index < 0 || index >= clock->caps.n_per_out)
return -EINVAL;
periodic_output(clock, rq, index, on);
return 0;
@@ -530,7 +534,7 @@ static void recalibrate(struct dp83640_clock *clock)
struct phy_device *master = clock->chosen->phydev;
u16 cfg0, evnt, ptp_trig, trigger, val;
- trigger = n_ext_ts + n_per_out;
+ trigger = clock->caps.n_ext_ts + clock->caps.n_per_out;
mutex_lock(&clock->extreg_lock);
@@ -554,7 +558,7 @@ static void recalibrate(struct dp83640_clock *clock)
*/
evnt = EVNT_WR | EVNT_RISE | EVNT_SINGLE;
evnt |= (trigger & EVNT_SEL_MASK) << EVNT_SEL_SHIFT;
- evnt |= (calibrate_pin & EVNT_GPIO_MASK) << EVNT_GPIO_SHIFT;
+ evnt |= (clock->calibrate_pin & EVNT_GPIO_MASK) << EVNT_GPIO_SHIFT;
list_for_each(this, &clock->phylist) {
tmp = list_entry(this, struct dp83640_private, list);
@@ -567,7 +571,7 @@ static void recalibrate(struct dp83640_clock *clock)
*/
ptp_trig = TRIG_WR | TRIG_IF_LATE | TRIG_PULSE;
ptp_trig |= (trigger & TRIG_CSEL_MASK) << TRIG_CSEL_SHIFT;
- ptp_trig |= (calibrate_pin & TRIG_GPIO_MASK) << TRIG_GPIO_SHIFT;
+ ptp_trig |= (clock->calibrate_pin & TRIG_GPIO_MASK) << TRIG_GPIO_SHIFT;
ext_write(0, master, PAGE5, PTP_TRIG, ptp_trig);
/* load trigger */
@@ -672,7 +676,7 @@ static int decode_evnt(struct dp83640_private *dp83640,
event.type = PTP_CLOCK_EXTTS;
event.timestamp = phy2txts(&dp83640->edata);
- for (i = 0; i < n_ext_ts; i++) {
+ for (i = 0; i < dp83640->clock->caps.n_ext_ts; i++) {
if (ext_status & exts_chan_to_edata(i)) {
event.index = i;
ptp_clock_event(dp83640->clock->ptp_clock, &event);
@@ -874,12 +878,11 @@ static void dp83640_clock_init(struct dp83640_clock *clock, struct mii_bus *bus)
mutex_init(&clock->extreg_lock);
mutex_init(&clock->clock_lock);
INIT_LIST_HEAD(&clock->phylist);
+ clock->calibrate_pin = -1;
clock->caps.owner = THIS_MODULE;
sprintf(clock->caps.name, "dp83640 timer");
clock->caps.max_adj = 1953124;
clock->caps.n_alarm = 0;
- clock->caps.n_ext_ts = n_ext_ts;
- clock->caps.n_per_out = n_per_out;
clock->caps.pps = 0;
clock->caps.adjfreq = ptp_dp83640_adjfreq;
clock->caps.adjtime = ptp_dp83640_adjtime;
@@ -892,18 +895,6 @@ static void dp83640_clock_init(struct dp83640_clock *clock, struct mii_bus *bus)
get_device(&bus->dev);
}
-static int choose_this_phy(struct dp83640_clock *clock,
- struct phy_device *phydev)
-{
- if (chosen_phy == -1 && !clock->chosen)
- return 1;
-
- if (chosen_phy == phydev->addr)
- return 1;
-
- return 0;
-}
-
static struct dp83640_clock *dp83640_clock_get(struct dp83640_clock *clock)
{
if (clock)
@@ -949,6 +940,95 @@ static void dp83640_clock_put(struct dp83640_clock *clock)
mutex_unlock(&clock->clock_lock);
}
+#ifdef CONFIG_OF
+static int dp83640_probe_dt(struct device_node *node,
+ struct dp83640_private *dp83640)
+{
+ struct dp83640_clock *clock = dp83640->clock;
+ struct property *prop;
+ int err, proplen;
+
+ dp83640->slave = of_property_read_bool(node, "dp83640,slave");
+ if (!dp83640->slave && clock->chosen) {
+ pr_err("dp83640,slave must be set if more than one device on the same bus");
+ return -EINVAL;
+ }
+
+ prop = of_find_property(node, "dp83640,perout-pins", &proplen);
+ if (prop) {
+ if (dp83640->slave) {
+ pr_err("dp83640,perout-pins property can not be set together with dp83640,slave");
+ return -EINVAL;
+ }
+
+ clock->caps.n_per_out = proplen / sizeof(u32);
+ if (clock->caps.n_per_out > N_EXT) {
+ pr_err("dp83640,perout-pins may not have more than %d entries",
+ N_EXT);
+ return -EINVAL;
+ }
+ err = of_property_read_u32_array(node, "dp83640,perout-pins",
+ clock->perout_pins,
+ clock->caps.n_per_out);
+ if (err < 0)
+ return err;
+ }
+
+ prop = of_find_property(node, "dp83640,extts-pins", &proplen);
+ if (prop) {
+ if (dp83640->slave) {
+ pr_err("dp83640,extts-pins property can not be set together with dp83640,slave");
+ return -EINVAL;
+ }
+
+ clock->caps.n_ext_ts = proplen / sizeof(u32);
+ if (clock->caps.n_ext_ts > N_EXT) {
+ pr_err("dp83640,extts-pins may not have more than %d entries",
+ N_EXT);
+ return -EINVAL;
+ }
+ err = of_property_read_u32_array(node, "dp83640,extts-pins",
+ clock->extts_pins,
+ clock->caps.n_ext_ts);
+ if (err < 0)
+ return err;
+ }
+
+ prop = of_find_property(node, "dp83640,calibrate-pin", &proplen);
+ if (prop) {
+ if (dp83640->slave) {
+ pr_err("dp83640,calibrate-pin property can not be set together with dp83640,slave");
+ return -EINVAL;
+ }
+ of_property_read_u32(node, "dp83640,calibrate-pin",
+ &clock->calibrate_pin);
+ }
+
+ if (!dp83640->slave) {
+ if (clock->caps.n_per_out + clock->caps.n_ext_ts +
+ (clock->calibrate_pin != -1 ? 1 : 0) > N_EXT) {
+ pr_err("Too many pins configured");
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+static const struct of_device_id dp83640_of_match_table[] = {
+ { .compatible = "national,dp83640", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, dp83640_of_match_table);
+#else
+
+static inline int dp83640_probe_dt(struct device_node *node,
+ struct dp83640_private *dp83640)
+{
+ return 0;
+}
+#endif
+
static int dp83640_probe(struct phy_device *phydev)
{
struct dp83640_clock *clock;
@@ -966,7 +1046,24 @@ static int dp83640_probe(struct phy_device *phydev)
if (!dp83640)
goto no_memory;
+ dp83640->clock = clock;
dp83640->phydev = phydev;
+
+ if (phydev->dev.of_node) {
+ err = dp83640_probe_dt(phydev->dev.of_node, dp83640);
+ if (err)
+ return err;
+ } else {
+ clock->calibrate_pin = calibrate_pin;
+ memcpy(clock->perout_pins, perout_pins,
+ sizeof(clock->perout_pins));
+ memcpy(clock->extts_pins, extts_pins,
+ sizeof(clock->extts_pins));
+ if (clock->chosen ||
+ (chosen_phy != -1 && phydev->addr != chosen_phy))
+ dp83640->slave = true;
+ }
+
INIT_WORK(&dp83640->ts_work, rx_timestamp_work);
INIT_LIST_HEAD(&dp83640->rxts);
@@ -980,9 +1077,7 @@ static int dp83640_probe(struct phy_device *phydev)
skb_queue_head_init(&dp83640->rx_queue);
skb_queue_head_init(&dp83640->tx_queue);
- dp83640->clock = clock;
-
- if (choose_this_phy(clock, phydev)) {
+ if (!dp83640->slave) {
clock->chosen = dp83640;
clock->ptp_clock = ptp_clock_register(&clock->caps, &phydev->dev);
if (IS_ERR(clock->ptp_clock)) {
@@ -1327,7 +1422,10 @@ static struct phy_driver dp83640_driver = {
.hwtstamp = dp83640_hwtstamp,
.rxtstamp = dp83640_rxtstamp,
.txtstamp = dp83640_txtstamp,
- .driver = {.owner = THIS_MODULE,}
+ .driver = {
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(dp83640_of_match_table),
+ }
};
static int __init dp83640_init(void)
--
1.8.5.3
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v2 1/2] dp83640: Support a configurable number of periodic outputs
2014-02-11 15:29 ` [PATCH v2 1/2] dp83640: Support a configurable number of periodic outputs Stefan Sørensen
@ 2014-02-11 20:09 ` Richard Cochran
2014-02-13 14:21 ` Stefan Sørensen
0 siblings, 1 reply; 7+ messages in thread
From: Richard Cochran @ 2014-02-11 20:09 UTC (permalink / raw)
To: Stefan Sørensen
Cc: grant.likely, robh+dt, mark.rutland, netdev, linux-kernel,
devicetree
On Tue, Feb 11, 2014 at 04:29:21PM +0100, Stefan Sørensen wrote:
> diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c
> index 547725f..d4fe95d 100644
> --- a/drivers/net/phy/dp83640.c
> +++ b/drivers/net/phy/dp83640.c
> @@ -38,15 +38,11 @@
> #define LAYER4 0x02
> #define LAYER2 0x01
> #define MAX_RXTS 64
> -#define N_EXT_TS 6
> +#define N_EXT 8
> #define PSF_PTPVER 2
> #define PSF_EVNT 0x4000
> #define PSF_RX 0x2000
> #define PSF_TX 0x1000
> -#define EXT_EVENT 1
Regarding this EXT_EVENT thing ...
> @@ -430,12 +419,12 @@ static int ptp_dp83640_enable(struct ptp_clock_info *ptp,
> switch (rq->type) {
> case PTP_CLK_REQ_EXTTS:
> index = rq->extts.index;
> - if (index < 0 || index >= N_EXT_TS)
> + if (index < 0 || index >= n_ext_ts)
> return -EINVAL;
> - event_num = EXT_EVENT + index;
> + event_num = index;
there was a mapping between the "event numbers" and the external time
stamp channels. I don't remember off the top of my head why this these
two differ by one, but there was a good reason.
Are you sure this is still working with this change?
I am especially wondering about the event decoding here:
> @@ -642,7 +631,7 @@ static void recalibrate(struct dp83640_clock *clock)
>
> static inline u16 exts_chan_to_edata(int ch)
> {
> - return 1 << ((ch + EXT_EVENT) * 2);
> + return 1 << ((ch) * 2);
> }
Maybe I am just paranoid, but can you remind me how these event
numbers are supposed to work, before and after the change?
Thanks,
Richard
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 2/2] dp83640: Get pin and master/slave configuration from DT
2014-02-11 15:29 ` [PATCH v2 2/2] dp83640: Get pin and master/slave configuration from DT Stefan Sørensen
@ 2014-02-11 20:19 ` Richard Cochran
2014-02-13 14:23 ` Stefan Sørensen
0 siblings, 1 reply; 7+ messages in thread
From: Richard Cochran @ 2014-02-11 20:19 UTC (permalink / raw)
To: Stefan Sørensen
Cc: grant.likely, robh+dt, mark.rutland, netdev, linux-kernel,
devicetree
On Tue, Feb 11, 2014 at 04:29:22PM +0100, Stefan Sørensen wrote:
> diff --git a/Documentation/devicetree/bindings/net/dp83640.txt b/Documentation/devicetree/bindings/net/dp83640.txt
> new file mode 100644
> index 0000000..b9a57c0
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/dp83640.txt
> @@ -0,0 +1,29 @@
> +Required properties for the National DP83640 ethernet phy:
> +
> +- compatible : Must contain "national,dp83640"
> +
> +Optional properties:
> +
> +- dp83640,slave: If present, this phy will be slave to another dp83640
> + on the same mdio bus.
Wouldn't it be more natural to have one "dp83640,master" property
rather than multiple slave properties?
> @@ -949,6 +940,95 @@ static void dp83640_clock_put(struct dp83640_clock *clock)
> mutex_unlock(&clock->clock_lock);
> }
>
> +#ifdef CONFIG_OF
> +static int dp83640_probe_dt(struct device_node *node,
> + struct dp83640_private *dp83640)
> +{
> + struct dp83640_clock *clock = dp83640->clock;
> + struct property *prop;
> + int err, proplen;
> +
> + dp83640->slave = of_property_read_bool(node, "dp83640,slave");
> + if (!dp83640->slave && clock->chosen) {
> + pr_err("dp83640,slave must be set if more than one device on the same bus");
Most of these pr_err lines are a bit _way_ too long for coding style.
> + return -EINVAL;
> + }
> +
> + prop = of_find_property(node, "dp83640,perout-pins", &proplen);
> + if (prop) {
> + if (dp83640->slave) {
> + pr_err("dp83640,perout-pins property can not be set together with dp83640,slave");
(Here especially and in the code that followed.)
Overall the series is looking better. I will try to test the non-DT
case later on this week.
Thanks,
Richard
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 1/2] dp83640: Support a configurable number of periodic outputs
2014-02-11 20:09 ` Richard Cochran
@ 2014-02-13 14:21 ` Stefan Sørensen
0 siblings, 0 replies; 7+ messages in thread
From: Stefan Sørensen @ 2014-02-13 14:21 UTC (permalink / raw)
To: Richard Cochran
Cc: grant.likely, robh+dt, mark.rutland, netdev, linux-kernel,
devicetree
On Tue, 2014-02-11 at 21:09 +0100, Richard Cochran wrote:
> > -#define EXT_EVENT 1
>
> Regarding this EXT_EVENT thing ...
>
> > @@ -430,12 +419,12 @@ static int ptp_dp83640_enable(struct ptp_clock_info *ptp,
> > switch (rq->type) {
> > case PTP_CLK_REQ_EXTTS:
> > index = rq->extts.index;
> > - if (index < 0 || index >= N_EXT_TS)
> > + if (index < 0 || index >= n_ext_ts)
> > return -EINVAL;
> > - event_num = EXT_EVENT + index;
> > + event_num = index;
>
> there was a mapping between the "event numbers" and the external time
> stamp channels. I don't remember off the top of my head why this these
> two differ by one, but there was a good reason.
I haven't seen anything in the documentation regarding this, output
triggers 0 and 1 are special, but the events should all behave the same.
Could be be a mixup between events and pins? Pin0 means disable the
event.
> Are you sure this is still working with this change?
It has been running with event 0 in one of our products for at least the
last 3 months....
> I am especially wondering about the event decoding here:
>
> > @@ -642,7 +631,7 @@ static void recalibrate(struct dp83640_clock *clock)
> >
> > static inline u16 exts_chan_to_edata(int ch)
> > {
> > - return 1 << ((ch + EXT_EVENT) * 2);
> > + return 1 << ((ch) * 2);
> > }
>
> Maybe I am just paranoid, but can you remind me how these event
> numbers are supposed to work, before and after the change?
The mapping was hardcoded to map events 0-5 to event channels 1-6, the
periodic output trigger at channel 6 and the calibration event+trigger
both at channel 7.
The patch will (at least in v3 that I will post shortly) change both the
event and trigger mapping to a direct mapping and keep the calibration
at channel 7.
Stefan
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 2/2] dp83640: Get pin and master/slave configuration from DT
2014-02-11 20:19 ` Richard Cochran
@ 2014-02-13 14:23 ` Stefan Sørensen
0 siblings, 0 replies; 7+ messages in thread
From: Stefan Sørensen @ 2014-02-13 14:23 UTC (permalink / raw)
To: Richard Cochran
Cc: grant.likely, robh+dt, mark.rutland, netdev, linux-kernel,
devicetree
On Tue, 2014-02-11 at 21:19 +0100, Richard Cochran wrote:
> > +- dp83640,slave: If present, this phy will be slave to another dp83640
> > + on the same mdio bus.
>
> Wouldn't it be more natural to have one "dp83640,master" property
> rather than multiple slave properties?
I wanted to keep the common case of a single phy simple, i.e. no need to
specify any master/slave properties.
> Most of these pr_err lines are a bit _way_ too long for coding style.
I will fix that in the next version.
Stefan
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2014-02-13 14:23 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-02-11 15:29 [PATCH v2 0/2] dp83640: Get pin and master/slave configuration from DT Stefan Sørensen
2014-02-11 15:29 ` [PATCH v2 1/2] dp83640: Support a configurable number of periodic outputs Stefan Sørensen
2014-02-11 20:09 ` Richard Cochran
2014-02-13 14:21 ` Stefan Sørensen
2014-02-11 15:29 ` [PATCH v2 2/2] dp83640: Get pin and master/slave configuration from DT Stefan Sørensen
2014-02-11 20:19 ` Richard Cochran
2014-02-13 14:23 ` Stefan Sørensen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).