Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

clk: microchip: mpfs: add reset controller

Add a reset controller to PolarFire SoC's clock driver. This reset
controller is registered as an aux device and read/write functions
exported to the drivers namespace so that the reset controller can
access the peripheral device reset register.

Reviewed-by: Daire McNamara <daire.mcnamara@microchip.com>
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
Reviewed-by: Claudiu Beznea <claudiu.beznea@microchip.com>
Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
Link: https://lore.kernel.org/r/20220909123123.2699583-5-conor.dooley@microchip.com

authored by

Conor Dooley and committed by
Claudiu Beznea
b56bae2d 89b16523

+107 -12
+1
drivers/clk/microchip/Kconfig
··· 6 6 config MCHP_CLK_MPFS 7 7 bool "Clk driver for PolarFire SoC" 8 8 depends on (RISCV && SOC_MICROCHIP_POLARFIRE) || COMPILE_TEST 9 + select AUXILIARY_BUS 9 10 help 10 11 Supports Clock Configuration for PolarFire SoC
+98 -12
drivers/clk/microchip/clk-mpfs.c
··· 3 3 * Daire McNamara,<daire.mcnamara@microchip.com> 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 ··· 30 28 #define MSSPLL_FIXED_DIV 4u 31 29 32 30 struct mpfs_clock_data { 31 + struct device *dev; 33 32 void __iomem *base; 34 33 void __iomem *msspll_base; 35 34 struct clk_hw_onecell_data hw_data; ··· 310 307 311 308 spin_lock_irqsave(&mpfs_clk_lock, flags); 312 309 313 - reg = readl_relaxed(base_addr + REG_SUBBLK_RESET_CR); 314 - val = reg & ~(1u << periph->shift); 315 - writel_relaxed(val, base_addr + REG_SUBBLK_RESET_CR); 316 - 317 310 reg = readl_relaxed(base_addr + REG_SUBBLK_CLOCK_CR); 318 311 val = reg | (1u << periph->shift); 319 312 writel_relaxed(val, base_addr + REG_SUBBLK_CLOCK_CR); ··· 343 344 void __iomem *base_addr = periph_hw->sys_base; 344 345 u32 reg; 345 346 346 - reg = readl_relaxed(base_addr + REG_SUBBLK_RESET_CR); 347 - if ((reg & (1u << periph->shift)) == 0u) { 348 - reg = readl_relaxed(base_addr + REG_SUBBLK_CLOCK_CR); 349 - if (reg & (1u << periph->shift)) 350 - return 1; 351 - } 347 + reg = readl_relaxed(base_addr + REG_SUBBLK_CLOCK_CR); 348 + if (reg & (1u << periph->shift)) 349 + return 1; 352 350 353 351 return 0; 354 352 } ··· 441 445 return 0; 442 446 } 443 447 448 + /* 449 + * Peripheral clock resets 450 + */ 451 + 452 + #if IS_ENABLED(CONFIG_RESET_CONTROLLER) 453 + 454 + u32 mpfs_reset_read(struct device *dev) 455 + { 456 + struct mpfs_clock_data *clock_data = dev_get_drvdata(dev->parent); 457 + 458 + return readl_relaxed(clock_data->base + REG_SUBBLK_RESET_CR); 459 + } 460 + EXPORT_SYMBOL_NS_GPL(mpfs_reset_read, MCHP_CLK_MPFS); 461 + 462 + void mpfs_reset_write(struct device *dev, u32 val) 463 + { 464 + struct mpfs_clock_data *clock_data = dev_get_drvdata(dev->parent); 465 + 466 + writel_relaxed(val, clock_data->base + REG_SUBBLK_RESET_CR); 467 + } 468 + EXPORT_SYMBOL_NS_GPL(mpfs_reset_write, MCHP_CLK_MPFS); 469 + 470 + static void mpfs_reset_unregister_adev(void *_adev) 471 + { 472 + struct auxiliary_device *adev = _adev; 473 + 474 + auxiliary_device_delete(adev); 475 + } 476 + 477 + static void mpfs_reset_adev_release(struct device *dev) 478 + { 479 + struct auxiliary_device *adev = to_auxiliary_dev(dev); 480 + 481 + auxiliary_device_uninit(adev); 482 + 483 + kfree(adev); 484 + } 485 + 486 + static struct auxiliary_device *mpfs_reset_adev_alloc(struct mpfs_clock_data *clk_data) 487 + { 488 + struct auxiliary_device *adev; 489 + int ret; 490 + 491 + adev = kzalloc(sizeof(*adev), GFP_KERNEL); 492 + if (!adev) 493 + return ERR_PTR(-ENOMEM); 494 + 495 + adev->name = "reset-mpfs"; 496 + adev->dev.parent = clk_data->dev; 497 + adev->dev.release = mpfs_reset_adev_release; 498 + adev->id = 666u; 499 + 500 + ret = auxiliary_device_init(adev); 501 + if (ret) { 502 + kfree(adev); 503 + return ERR_PTR(ret); 504 + } 505 + 506 + return adev; 507 + } 508 + 509 + static int mpfs_reset_controller_register(struct mpfs_clock_data *clk_data) 510 + { 511 + struct auxiliary_device *adev; 512 + int ret; 513 + 514 + adev = mpfs_reset_adev_alloc(clk_data); 515 + if (IS_ERR(adev)) 516 + return PTR_ERR(adev); 517 + 518 + ret = auxiliary_device_add(adev); 519 + if (ret) { 520 + auxiliary_device_uninit(adev); 521 + return ret; 522 + } 523 + 524 + return devm_add_action_or_reset(clk_data->dev, mpfs_reset_unregister_adev, adev); 525 + } 526 + 527 + #else /* !CONFIG_RESET_CONTROLLER */ 528 + 529 + static int mpfs_reset_controller_register(struct mpfs_clock_data *clk_data) 530 + { 531 + return 0; 532 + } 533 + 534 + #endif /* !CONFIG_RESET_CONTROLLER */ 535 + 444 536 static int mpfs_clk_probe(struct platform_device *pdev) 445 537 { 446 538 struct device *dev = &pdev->dev; ··· 553 469 return PTR_ERR(clk_data->msspll_base); 554 470 555 471 clk_data->hw_data.num = num_clks; 472 + clk_data->dev = dev; 473 + dev_set_drvdata(dev, clk_data); 556 474 557 475 ret = mpfs_clk_register_mssplls(dev, mpfs_msspll_clks, ARRAY_SIZE(mpfs_msspll_clks), 558 476 clk_data); ··· 574 488 if (ret) 575 489 return ret; 576 490 577 - return ret; 491 + return mpfs_reset_controller_register(clk_data); 578 492 } 579 493 580 494 static const struct of_device_id mpfs_clk_of_match_table[] = { 581 495 { .compatible = "microchip,mpfs-clkcfg", }, 582 496 {} 583 497 }; 584 - MODULE_DEVICE_TABLE(of, mpfs_clk_match_table); 498 + MODULE_DEVICE_TABLE(of, mpfs_clk_of_match_table); 585 499 586 500 static struct platform_driver mpfs_clk_driver = { 587 501 .probe = mpfs_clk_probe,
+8
include/soc/microchip/mpfs.h
··· 40 40 41 41 #endif /* if IS_ENABLED(CONFIG_POLARFIRE_SOC_SYS_CTRL) */ 42 42 43 + #if IS_ENABLED(CONFIG_MCHP_CLK_MPFS) 44 + 45 + u32 mpfs_reset_read(struct device *dev); 46 + 47 + void mpfs_reset_write(struct device *dev, u32 val); 48 + 49 + #endif /* if IS_ENABLED(CONFIG_MCHP_CLK_MPFS) */ 50 + 43 51 #endif /* __SOC_MPFS_H__ */