3
3
* Daire McNamara,<[email protected] >
4
4
* Copyright (C) 2020 Microchip Technology Inc. All rights reserved.
5
5
*/
6
+ #include <linux/auxiliary_bus.h>
6
7
#include <linux/clk-provider.h>
7
8
#include <linux/io.h>
8
9
#include <linux/module.h>
9
10
#include <linux/platform_device.h>
10
11
#include <linux/slab.h>
11
12
#include <dt-bindings/clock/microchip,mpfs-clock.h>
13
+ #include <soc/microchip/mpfs.h>
12
14
13
15
/* address offset of control registers */
14
16
#define REG_MSSPLL_REF_CR 0x08u
28
30
#define MSSPLL_FIXED_DIV 4u
29
31
30
32
struct mpfs_clock_data {
33
+ struct device * dev ;
31
34
void __iomem * base ;
32
35
void __iomem * msspll_base ;
33
36
struct clk_hw_onecell_data hw_data ;
@@ -307,10 +310,6 @@ static int mpfs_periph_clk_enable(struct clk_hw *hw)
307
310
308
311
spin_lock_irqsave (& mpfs_clk_lock , flags );
309
312
310
- reg = readl_relaxed (base_addr + REG_SUBBLK_RESET_CR );
311
- val = reg & ~(1u << periph -> shift );
312
- writel_relaxed (val , base_addr + REG_SUBBLK_RESET_CR );
313
-
314
313
reg = readl_relaxed (base_addr + REG_SUBBLK_CLOCK_CR );
315
314
val = reg | (1u << periph -> shift );
316
315
writel_relaxed (val , base_addr + REG_SUBBLK_CLOCK_CR );
@@ -344,12 +343,9 @@ static int mpfs_periph_clk_is_enabled(struct clk_hw *hw)
344
343
void __iomem * base_addr = periph_hw -> sys_base ;
345
344
u32 reg ;
346
345
347
- reg = readl_relaxed (base_addr + REG_SUBBLK_RESET_CR );
348
- if ((reg & (1u << periph -> shift )) == 0u ) {
349
- reg = readl_relaxed (base_addr + REG_SUBBLK_CLOCK_CR );
350
- if (reg & (1u << periph -> shift ))
351
- return 1 ;
352
- }
346
+ reg = readl_relaxed (base_addr + REG_SUBBLK_CLOCK_CR );
347
+ if (reg & (1u << periph -> shift ))
348
+ return 1 ;
353
349
354
350
return 0 ;
355
351
}
@@ -445,6 +441,94 @@ static int mpfs_clk_register_periphs(struct device *dev, struct mpfs_periph_hw_c
445
441
return 0 ;
446
442
}
447
443
444
+ /*
445
+ * Peripheral clock resets
446
+ */
447
+
448
+ #if IS_ENABLED (CONFIG_RESET_CONTROLLER )
449
+
450
+ u32 mpfs_reset_read (struct device * dev )
451
+ {
452
+ struct mpfs_clock_data * clock_data = dev_get_drvdata (dev -> parent );
453
+
454
+ return readl_relaxed (clock_data -> base + REG_SUBBLK_RESET_CR );
455
+ }
456
+ EXPORT_SYMBOL_NS_GPL (mpfs_reset_read , MCHP_CLK_MPFS );
457
+
458
+ void mpfs_reset_write (struct device * dev , u32 val )
459
+ {
460
+ struct mpfs_clock_data * clock_data = dev_get_drvdata (dev -> parent );
461
+
462
+ writel_relaxed (val , clock_data -> base + REG_SUBBLK_RESET_CR );
463
+ }
464
+ EXPORT_SYMBOL_NS_GPL (mpfs_reset_write , MCHP_CLK_MPFS );
465
+
466
+ static void mpfs_reset_unregister_adev (void * _adev )
467
+ {
468
+ struct auxiliary_device * adev = _adev ;
469
+
470
+ auxiliary_device_delete (adev );
471
+ }
472
+
473
+ static void mpfs_reset_adev_release (struct device * dev )
474
+ {
475
+ struct auxiliary_device * adev = to_auxiliary_dev (dev );
476
+
477
+ auxiliary_device_uninit (adev );
478
+
479
+ kfree (adev );
480
+ }
481
+
482
+ static struct auxiliary_device * mpfs_reset_adev_alloc (struct mpfs_clock_data * clk_data )
483
+ {
484
+ struct auxiliary_device * adev ;
485
+ int ret ;
486
+
487
+ adev = kzalloc (sizeof (* adev ), GFP_KERNEL );
488
+ if (!adev )
489
+ return ERR_PTR (- ENOMEM );
490
+
491
+ adev -> name = "reset-mpfs" ;
492
+ adev -> dev .parent = clk_data -> dev ;
493
+ adev -> dev .release = mpfs_reset_adev_release ;
494
+ adev -> id = 666u ;
495
+
496
+ ret = auxiliary_device_init (adev );
497
+ if (ret ) {
498
+ kfree (adev );
499
+ return ERR_PTR (ret );
500
+ }
501
+
502
+ return adev ;
503
+ }
504
+
505
+ static int mpfs_reset_controller_register (struct mpfs_clock_data * clk_data )
506
+ {
507
+ struct auxiliary_device * adev ;
508
+ int ret ;
509
+
510
+ adev = mpfs_reset_adev_alloc (clk_data );
511
+ if (IS_ERR (adev ))
512
+ return PTR_ERR (adev );
513
+
514
+ ret = auxiliary_device_add (adev );
515
+ if (ret ) {
516
+ auxiliary_device_uninit (adev );
517
+ return ret ;
518
+ }
519
+
520
+ return devm_add_action_or_reset (clk_data -> dev , mpfs_reset_unregister_adev , adev );
521
+ }
522
+
523
+ #else /* !CONFIG_RESET_CONTROLLER */
524
+
525
+ static int mpfs_reset_controller_register (struct mpfs_clock_data * clk_data )
526
+ {
527
+ return 0 ;
528
+ }
529
+
530
+ #endif /* !CONFIG_RESET_CONTROLLER */
531
+
448
532
static int mpfs_clk_probe (struct platform_device * pdev )
449
533
{
450
534
struct device * dev = & pdev -> dev ;
@@ -469,6 +553,8 @@ static int mpfs_clk_probe(struct platform_device *pdev)
469
553
return PTR_ERR (clk_data -> msspll_base );
470
554
471
555
clk_data -> hw_data .num = num_clks ;
556
+ clk_data -> dev = dev ;
557
+ dev_set_drvdata (dev , clk_data );
472
558
473
559
ret = mpfs_clk_register_mssplls (dev , mpfs_msspll_clks , ARRAY_SIZE (mpfs_msspll_clks ),
474
560
clk_data );
@@ -488,14 +574,14 @@ static int mpfs_clk_probe(struct platform_device *pdev)
488
574
if (ret )
489
575
return ret ;
490
576
491
- return ret ;
577
+ return mpfs_reset_controller_register ( clk_data ) ;
492
578
}
493
579
494
580
static const struct of_device_id mpfs_clk_of_match_table [] = {
495
581
{ .compatible = "microchip,mpfs-clkcfg" , },
496
582
{}
497
583
};
498
- MODULE_DEVICE_TABLE (of , mpfs_clk_match_table );
584
+ MODULE_DEVICE_TABLE (of , mpfs_clk_of_match_table );
499
585
500
586
static struct platform_driver mpfs_clk_driver = {
501
587
.probe = mpfs_clk_probe ,
0 commit comments