Files
SDK_SG200x_V2/linux_5.10/drivers/reset/clk-reset-cvitek.c
carbon 0545e9dc6d init version 2024-05-07
commit d1edce71135cc6d98c0a4b5729774542b676e769
Author: sophgo-forum-service <forum_service@sophgo.com>
Date:   Fri Mar 15 16:07:33 2024 +0800

    [fix] recommend using ssh method to clone repo.
    [fix] fix sensor driver repo branch name.
2024-05-07 19:36:36 +08:00

126 lines
3.1 KiB
C

/*
* Bitmain SoCs Reset Controller driver
*
* Copyright (c) 2018 Bitmain Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <linux/err.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/reset-controller.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/types.h>
#define BITS_PER_REG 32
struct bm_reset_data {
spinlock_t lock;
void __iomem *membase;
struct reset_controller_dev rcdev;
};
static int bm_reset_assert(struct reset_controller_dev *rcdev,
unsigned long id)
{
struct bm_reset_data *data = container_of(rcdev,
struct bm_reset_data,
rcdev);
int bank = id / BITS_PER_REG;
int offset = id % BITS_PER_REG;
unsigned long flags;
u32 reg;
spin_lock_irqsave(&data->lock, flags);
reg = readl(data->membase + (bank * 4));
writel(reg & ~BIT(offset), data->membase + (bank * 4));
spin_unlock_irqrestore(&data->lock, flags);
return 0;
}
static int bm_reset_deassert(struct reset_controller_dev *rcdev,
unsigned long id)
{
struct bm_reset_data *data = container_of(rcdev,
struct bm_reset_data,
rcdev);
int bank = id / BITS_PER_REG;
int offset = id % BITS_PER_REG;
unsigned long flags;
u32 reg;
spin_lock_irqsave(&data->lock, flags);
reg = readl(data->membase + (bank * 4));
writel(reg | BIT(offset), data->membase + (bank * 4));
spin_unlock_irqrestore(&data->lock, flags);
return 0;
}
static const struct reset_control_ops bm_reset_ops = {
.assert = bm_reset_assert,
.deassert = bm_reset_deassert,
};
static const struct of_device_id bm_reset_dt_ids[] = {
{ .compatible = "cvitek,clk-reset", },
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, bm_reset_dt_ids);
static int bm_reset_probe(struct platform_device *pdev)
{
struct bm_reset_data *data;
struct resource *res;
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
data->membase = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(data->membase))
return PTR_ERR(data->membase);
spin_lock_init(&data->lock);
data->rcdev.owner = THIS_MODULE;
data->rcdev.nr_resets = (resource_size(res)>>2) * 32;
pr_info("clk reset: nr_reset=%d resource_size=%lld\n", data->rcdev.nr_resets, resource_size(res));
data->rcdev.ops = &bm_reset_ops;
data->rcdev.of_node = pdev->dev.of_node;
return devm_reset_controller_register(&pdev->dev, &data->rcdev);
}
static struct platform_driver bm_reset_driver = {
.probe = bm_reset_probe,
.driver = {
.name = "bm-clock-reset",
.of_match_table = bm_reset_dt_ids,
},
};
static int __init bm_clk_reset_init(void)
{
return platform_driver_register(&bm_reset_driver);
}
postcore_initcall(bm_clk_reset_init);
MODULE_AUTHOR("Wei Huang<wei.huang01@bitmain.com>");
MODULE_DESCRIPTION("Cvitek SoC Clock Reset Controoler Driver");
MODULE_LICENSE("GPL");