Skip to content

Commit 8a2c9a5

Browse files
grygoriySdavem330
authored andcommitted
net: ethernet: ti: cpts: rework initialization/deinitialization
The current implementation CPTS initialization and deinitialization (represented by cpts_register/unregister()) does too many static initialization from .ndo_open(), which is reasonable to do once at probe time instead, and also require caller to allocate memory for struct cpts, which is internal for CPTS driver in general. This patch splits CPTS initialization and deinitialization on two parts: - static initializtion cpts_create()/cpts_release() which expected to be executed when parent driver is probed/removed; - dynamic part cpts_register/unregister() which expected to be executed when network device is opened/closed. As result, current code of CPTS parent driver - CPSW - will be simplified (and it also will allow simplify adding support for Keystone 2 devices in the future), plus more initialization errors will be catched earlier. In addition, this change allows to clean up cpts.h for the case when CPTS is disabled. Signed-off-by: Grygorii Strashko <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 2a79df3 commit 8a2c9a5

File tree

3 files changed

+92
-57
lines changed

3 files changed

+92
-57
lines changed

drivers/net/ethernet/ti/cpsw.c

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1487,9 +1487,7 @@ static int cpsw_ndo_open(struct net_device *ndev)
14871487
if (ret < 0)
14881488
goto err_cleanup;
14891489

1490-
if (cpts_register(cpsw->dev, cpsw->cpts,
1491-
cpsw->data.cpts_clock_mult,
1492-
cpsw->data.cpts_clock_shift))
1490+
if (cpts_register(cpsw->cpts))
14931491
dev_err(priv->dev, "error registering cpts device\n");
14941492

14951493
}
@@ -2796,6 +2794,7 @@ static int cpsw_probe(struct platform_device *pdev)
27962794
struct cpdma_params dma_params;
27972795
struct cpsw_ale_params ale_params;
27982796
void __iomem *ss_regs;
2797+
void __iomem *cpts_regs;
27992798
struct resource *res, *ss_res;
28002799
const struct of_device_id *of_id;
28012800
struct gpio_descs *mode;
@@ -2823,12 +2822,6 @@ static int cpsw_probe(struct platform_device *pdev)
28232822
priv->dev = &ndev->dev;
28242823
priv->msg_enable = netif_msg_init(debug_level, CPSW_DEBUG);
28252824
cpsw->rx_packet_max = max(rx_packet_max, 128);
2826-
cpsw->cpts = devm_kzalloc(&pdev->dev, sizeof(struct cpts), GFP_KERNEL);
2827-
if (!cpsw->cpts) {
2828-
dev_err(&pdev->dev, "error allocating cpts\n");
2829-
ret = -ENOMEM;
2830-
goto clean_ndev_ret;
2831-
}
28322825

28332826
mode = devm_gpiod_get_array_optional(&pdev->dev, "mode", GPIOD_OUT_LOW);
28342827
if (IS_ERR(mode)) {
@@ -2916,7 +2909,7 @@ static int cpsw_probe(struct platform_device *pdev)
29162909
switch (cpsw->version) {
29172910
case CPSW_VERSION_1:
29182911
cpsw->host_port_regs = ss_regs + CPSW1_HOST_PORT_OFFSET;
2919-
cpsw->cpts->reg = ss_regs + CPSW1_CPTS_OFFSET;
2912+
cpts_regs = ss_regs + CPSW1_CPTS_OFFSET;
29202913
cpsw->hw_stats = ss_regs + CPSW1_HW_STATS;
29212914
dma_params.dmaregs = ss_regs + CPSW1_CPDMA_OFFSET;
29222915
dma_params.txhdp = ss_regs + CPSW1_STATERAM_OFFSET;
@@ -2930,7 +2923,7 @@ static int cpsw_probe(struct platform_device *pdev)
29302923
case CPSW_VERSION_3:
29312924
case CPSW_VERSION_4:
29322925
cpsw->host_port_regs = ss_regs + CPSW2_HOST_PORT_OFFSET;
2933-
cpsw->cpts->reg = ss_regs + CPSW2_CPTS_OFFSET;
2926+
cpts_regs = ss_regs + CPSW2_CPTS_OFFSET;
29342927
cpsw->hw_stats = ss_regs + CPSW2_HW_STATS;
29352928
dma_params.dmaregs = ss_regs + CPSW2_CPDMA_OFFSET;
29362929
dma_params.txhdp = ss_regs + CPSW2_STATERAM_OFFSET;
@@ -2997,6 +2990,14 @@ static int cpsw_probe(struct platform_device *pdev)
29972990
goto clean_dma_ret;
29982991
}
29992992

2993+
cpsw->cpts = cpts_create(cpsw->dev, cpts_regs,
2994+
cpsw->data.cpts_clock_mult,
2995+
cpsw->data.cpts_clock_shift);
2996+
if (IS_ERR(cpsw->cpts)) {
2997+
ret = PTR_ERR(cpsw->cpts);
2998+
goto clean_ale_ret;
2999+
}
3000+
30003001
ndev->irq = platform_get_irq(pdev, 1);
30013002
if (ndev->irq < 0) {
30023003
dev_err(priv->dev, "error getting irq resource\n");
@@ -3112,6 +3113,7 @@ static int cpsw_remove(struct platform_device *pdev)
31123113
unregister_netdev(cpsw->slaves[1].ndev);
31133114
unregister_netdev(ndev);
31143115

3116+
cpts_release(cpsw->cpts);
31153117
cpsw_ale_destroy(cpsw->ale);
31163118
cpdma_ctlr_destroy(cpsw->dma);
31173119
cpsw_remove_dt(pdev);

drivers/net/ethernet/ti/cpts.c

Lines changed: 58 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -248,24 +248,6 @@ static void cpts_overflow_check(struct work_struct *work)
248248
schedule_delayed_work(&cpts->overflow_work, CPTS_OVERFLOW_PERIOD);
249249
}
250250

251-
static void cpts_clk_init(struct device *dev, struct cpts *cpts)
252-
{
253-
if (!cpts->refclk) {
254-
cpts->refclk = devm_clk_get(dev, "cpts");
255-
if (IS_ERR(cpts->refclk)) {
256-
dev_err(dev, "Failed to get cpts refclk\n");
257-
cpts->refclk = NULL;
258-
return;
259-
}
260-
}
261-
clk_prepare_enable(cpts->refclk);
262-
}
263-
264-
static void cpts_clk_release(struct cpts *cpts)
265-
{
266-
clk_disable_unprepare(cpts->refclk);
267-
}
268-
269251
static int cpts_match(struct sk_buff *skb, unsigned int ptp_class,
270252
u16 ts_seqid, u8 ts_msgtype)
271253
{
@@ -372,34 +354,23 @@ void cpts_tx_timestamp(struct cpts *cpts, struct sk_buff *skb)
372354
}
373355
EXPORT_SYMBOL_GPL(cpts_tx_timestamp);
374356

375-
int cpts_register(struct device *dev, struct cpts *cpts,
376-
u32 mult, u32 shift)
357+
int cpts_register(struct cpts *cpts)
377358
{
378359
int err, i;
379360

380-
cpts->info = cpts_info;
381-
spin_lock_init(&cpts->lock);
382-
383-
cpts->cc.read = cpts_systim_read;
384-
cpts->cc.mask = CLOCKSOURCE_MASK(32);
385-
cpts->cc_mult = mult;
386-
cpts->cc.mult = mult;
387-
cpts->cc.shift = shift;
388-
389361
INIT_LIST_HEAD(&cpts->events);
390362
INIT_LIST_HEAD(&cpts->pool);
391363
for (i = 0; i < CPTS_MAX_EVENTS; i++)
392364
list_add(&cpts->pool_data[i].list, &cpts->pool);
393365

394-
cpts_clk_init(dev, cpts);
366+
clk_enable(cpts->refclk);
367+
395368
cpts_write32(cpts, CPTS_EN, control);
396369
cpts_write32(cpts, TS_PEND_EN, int_enable);
397370

398371
timecounter_init(&cpts->tc, &cpts->cc, ktime_to_ns(ktime_get_real()));
399372

400-
INIT_DELAYED_WORK(&cpts->overflow_work, cpts_overflow_check);
401-
402-
cpts->clock = ptp_clock_register(&cpts->info, dev);
373+
cpts->clock = ptp_clock_register(&cpts->info, cpts->dev);
403374
if (IS_ERR(cpts->clock)) {
404375
err = PTR_ERR(cpts->clock);
405376
cpts->clock = NULL;
@@ -412,27 +383,73 @@ int cpts_register(struct device *dev, struct cpts *cpts,
412383
return 0;
413384

414385
err_ptp:
415-
if (cpts->refclk)
416-
cpts_clk_release(cpts);
386+
clk_disable(cpts->refclk);
417387
return err;
418388
}
419389
EXPORT_SYMBOL_GPL(cpts_register);
420390

421391
void cpts_unregister(struct cpts *cpts)
422392
{
423-
if (cpts->clock) {
424-
ptp_clock_unregister(cpts->clock);
425-
cancel_delayed_work_sync(&cpts->overflow_work);
426-
}
393+
if (WARN_ON(!cpts->clock))
394+
return;
395+
396+
cancel_delayed_work_sync(&cpts->overflow_work);
397+
398+
ptp_clock_unregister(cpts->clock);
399+
cpts->clock = NULL;
427400

428401
cpts_write32(cpts, 0, int_enable);
429402
cpts_write32(cpts, 0, control);
430403

431-
if (cpts->refclk)
432-
cpts_clk_release(cpts);
404+
clk_disable(cpts->refclk);
433405
}
434406
EXPORT_SYMBOL_GPL(cpts_unregister);
435407

408+
struct cpts *cpts_create(struct device *dev, void __iomem *regs,
409+
u32 mult, u32 shift)
410+
{
411+
struct cpts *cpts;
412+
413+
cpts = devm_kzalloc(dev, sizeof(*cpts), GFP_KERNEL);
414+
if (!cpts)
415+
return ERR_PTR(-ENOMEM);
416+
417+
cpts->dev = dev;
418+
cpts->reg = (struct cpsw_cpts __iomem *)regs;
419+
spin_lock_init(&cpts->lock);
420+
INIT_DELAYED_WORK(&cpts->overflow_work, cpts_overflow_check);
421+
422+
cpts->refclk = devm_clk_get(dev, "cpts");
423+
if (IS_ERR(cpts->refclk)) {
424+
dev_err(dev, "Failed to get cpts refclk\n");
425+
return ERR_PTR(PTR_ERR(cpts->refclk));
426+
}
427+
428+
clk_prepare(cpts->refclk);
429+
430+
cpts->cc.read = cpts_systim_read;
431+
cpts->cc.mask = CLOCKSOURCE_MASK(32);
432+
cpts->cc.shift = shift;
433+
cpts->cc_mult = mult;
434+
cpts->cc.mult = mult;
435+
cpts->info = cpts_info;
436+
437+
return cpts;
438+
}
439+
EXPORT_SYMBOL_GPL(cpts_create);
440+
441+
void cpts_release(struct cpts *cpts)
442+
{
443+
if (!cpts)
444+
return;
445+
446+
if (WARN_ON(!cpts->refclk))
447+
return;
448+
449+
clk_unprepare(cpts->refclk);
450+
}
451+
EXPORT_SYMBOL_GPL(cpts_release);
452+
436453
MODULE_LICENSE("GPL v2");
437454
MODULE_DESCRIPTION("TI CPTS driver");
438455
MODULE_AUTHOR("Richard Cochran <[email protected]>");

drivers/net/ethernet/ti/cpts.h

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
#ifndef _TI_CPTS_H_
2121
#define _TI_CPTS_H_
2222

23+
#if IS_ENABLED(CONFIG_TI_CPTS)
24+
2325
#include <linux/clk.h>
2426
#include <linux/clkdev.h>
2527
#include <linux/clocksource.h>
@@ -108,10 +110,10 @@ struct cpts_event {
108110
};
109111

110112
struct cpts {
113+
struct device *dev;
111114
struct cpsw_cpts __iomem *reg;
112115
int tx_enable;
113116
int rx_enable;
114-
#if IS_ENABLED(CONFIG_TI_CPTS)
115117
struct ptp_clock_info info;
116118
struct ptp_clock *clock;
117119
spinlock_t lock; /* protects time registers */
@@ -124,14 +126,15 @@ struct cpts {
124126
struct list_head events;
125127
struct list_head pool;
126128
struct cpts_event pool_data[CPTS_MAX_EVENTS];
127-
#endif
128129
};
129130

130-
#if IS_ENABLED(CONFIG_TI_CPTS)
131131
void cpts_rx_timestamp(struct cpts *cpts, struct sk_buff *skb);
132132
void cpts_tx_timestamp(struct cpts *cpts, struct sk_buff *skb);
133-
int cpts_register(struct device *dev, struct cpts *cpts, u32 mult, u32 shift);
133+
int cpts_register(struct cpts *cpts);
134134
void cpts_unregister(struct cpts *cpts);
135+
struct cpts *cpts_create(struct device *dev, void __iomem *regs,
136+
u32 mult, u32 shift);
137+
void cpts_release(struct cpts *cpts);
135138

136139
static inline void cpts_rx_enable(struct cpts *cpts, int enable)
137140
{
@@ -154,15 +157,28 @@ static inline bool cpts_is_tx_enabled(struct cpts *cpts)
154157
}
155158

156159
#else
160+
struct cpts;
161+
157162
static inline void cpts_rx_timestamp(struct cpts *cpts, struct sk_buff *skb)
158163
{
159164
}
160165
static inline void cpts_tx_timestamp(struct cpts *cpts, struct sk_buff *skb)
161166
{
162167
}
163168

169+
static inline
170+
struct cpts *cpts_create(struct device *dev, void __iomem *regs,
171+
u32 mult, u32 shift)
172+
{
173+
return NULL;
174+
}
175+
176+
static inline void cpts_release(struct cpts *cpts)
177+
{
178+
}
179+
164180
static inline int
165-
cpts_register(struct device *dev, struct cpts *cpts, u32 mult, u32 shift)
181+
cpts_register(struct cpts *cpts)
166182
{
167183
return 0;
168184
}

0 commit comments

Comments
 (0)