Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) 2020 BAIKAL ELECTRONICS, JSC
0004  *
0005  * Authors:
0006  *   Serge Semin <Sergey.Semin@baikalelectronics.ru>
0007  *
0008  * Baikal-T1 AXI-bus driver
0009  */
0010 
0011 #include <linux/kernel.h>
0012 #include <linux/module.h>
0013 #include <linux/types.h>
0014 #include <linux/bitfield.h>
0015 #include <linux/device.h>
0016 #include <linux/atomic.h>
0017 #include <linux/regmap.h>
0018 #include <linux/platform_device.h>
0019 #include <linux/mfd/syscon.h>
0020 #include <linux/interrupt.h>
0021 #include <linux/io.h>
0022 #include <linux/nmi.h>
0023 #include <linux/of.h>
0024 #include <linux/clk.h>
0025 #include <linux/reset.h>
0026 #include <linux/sysfs.h>
0027 
0028 #define BT1_AXI_WERRL           0x110
0029 #define BT1_AXI_WERRH           0x114
0030 #define BT1_AXI_WERRH_TYPE      BIT(23)
0031 #define BT1_AXI_WERRH_ADDR_FLD      24
0032 #define BT1_AXI_WERRH_ADDR_MASK     GENMASK(31, BT1_AXI_WERRH_ADDR_FLD)
0033 
0034 /*
0035  * struct bt1_axi - Baikal-T1 AXI-bus private data
0036  * @dev: Pointer to the device structure.
0037  * @qos_regs: AXI Interconnect QoS tuning registers.
0038  * @sys_regs: Baikal-T1 System Controller registers map.
0039  * @irq: Errors IRQ number.
0040  * @aclk: AXI reference clock.
0041  * @arst: AXI Interconnect reset line.
0042  * @count: Number of errors detected.
0043  */
0044 struct bt1_axi {
0045     struct device *dev;
0046 
0047     void __iomem *qos_regs;
0048     struct regmap *sys_regs;
0049     int irq;
0050 
0051     struct clk *aclk;
0052 
0053     struct reset_control *arst;
0054 
0055     atomic_t count;
0056 };
0057 
0058 static irqreturn_t bt1_axi_isr(int irq, void *data)
0059 {
0060     struct bt1_axi *axi = data;
0061     u32 low = 0, high = 0;
0062 
0063     regmap_read(axi->sys_regs, BT1_AXI_WERRL, &low);
0064     regmap_read(axi->sys_regs, BT1_AXI_WERRH, &high);
0065 
0066     dev_crit_ratelimited(axi->dev,
0067         "AXI-bus fault %d: %s at 0x%x%08x\n",
0068         atomic_inc_return(&axi->count),
0069         high & BT1_AXI_WERRH_TYPE ? "no slave" : "slave protocol error",
0070         high, low);
0071 
0072     /*
0073      * Print backtrace on each CPU. This might be pointless if the fault
0074      * has happened on the same CPU as the IRQ handler is executed or
0075      * the other core proceeded further execution despite the error.
0076      * But if it's not, by looking at the trace we would get straight to
0077      * the cause of the problem.
0078      */
0079     trigger_all_cpu_backtrace();
0080 
0081     return IRQ_HANDLED;
0082 }
0083 
0084 static void bt1_axi_clear_data(void *data)
0085 {
0086     struct bt1_axi *axi = data;
0087     struct platform_device *pdev = to_platform_device(axi->dev);
0088 
0089     platform_set_drvdata(pdev, NULL);
0090 }
0091 
0092 static struct bt1_axi *bt1_axi_create_data(struct platform_device *pdev)
0093 {
0094     struct device *dev = &pdev->dev;
0095     struct bt1_axi *axi;
0096     int ret;
0097 
0098     axi = devm_kzalloc(dev, sizeof(*axi), GFP_KERNEL);
0099     if (!axi)
0100         return ERR_PTR(-ENOMEM);
0101 
0102     ret = devm_add_action(dev, bt1_axi_clear_data, axi);
0103     if (ret) {
0104         dev_err(dev, "Can't add AXI EHB data clear action\n");
0105         return ERR_PTR(ret);
0106     }
0107 
0108     axi->dev = dev;
0109     atomic_set(&axi->count, 0);
0110     platform_set_drvdata(pdev, axi);
0111 
0112     return axi;
0113 }
0114 
0115 static int bt1_axi_request_regs(struct bt1_axi *axi)
0116 {
0117     struct platform_device *pdev = to_platform_device(axi->dev);
0118     struct device *dev = axi->dev;
0119 
0120     axi->sys_regs = syscon_regmap_lookup_by_phandle(dev->of_node, "syscon");
0121     if (IS_ERR(axi->sys_regs)) {
0122         dev_err(dev, "Couldn't find syscon registers\n");
0123         return PTR_ERR(axi->sys_regs);
0124     }
0125 
0126     axi->qos_regs = devm_platform_ioremap_resource_byname(pdev, "qos");
0127     if (IS_ERR(axi->qos_regs))
0128         dev_err(dev, "Couldn't map AXI-bus QoS registers\n");
0129 
0130     return PTR_ERR_OR_ZERO(axi->qos_regs);
0131 }
0132 
0133 static int bt1_axi_request_rst(struct bt1_axi *axi)
0134 {
0135     int ret;
0136 
0137     axi->arst = devm_reset_control_get_optional_exclusive(axi->dev, "arst");
0138     if (IS_ERR(axi->arst))
0139         return dev_err_probe(axi->dev, PTR_ERR(axi->arst),
0140                      "Couldn't get reset control line\n");
0141 
0142     ret = reset_control_deassert(axi->arst);
0143     if (ret)
0144         dev_err(axi->dev, "Failed to deassert the reset line\n");
0145 
0146     return ret;
0147 }
0148 
0149 static void bt1_axi_disable_clk(void *data)
0150 {
0151     struct bt1_axi *axi = data;
0152 
0153     clk_disable_unprepare(axi->aclk);
0154 }
0155 
0156 static int bt1_axi_request_clk(struct bt1_axi *axi)
0157 {
0158     int ret;
0159 
0160     axi->aclk = devm_clk_get(axi->dev, "aclk");
0161     if (IS_ERR(axi->aclk))
0162         return dev_err_probe(axi->dev, PTR_ERR(axi->aclk),
0163                      "Couldn't get AXI Interconnect clock\n");
0164 
0165     ret = clk_prepare_enable(axi->aclk);
0166     if (ret) {
0167         dev_err(axi->dev, "Couldn't enable the AXI clock\n");
0168         return ret;
0169     }
0170 
0171     ret = devm_add_action_or_reset(axi->dev, bt1_axi_disable_clk, axi);
0172     if (ret)
0173         dev_err(axi->dev, "Can't add AXI clock disable action\n");
0174 
0175     return ret;
0176 }
0177 
0178 static int bt1_axi_request_irq(struct bt1_axi *axi)
0179 {
0180     struct platform_device *pdev = to_platform_device(axi->dev);
0181     int ret;
0182 
0183     axi->irq = platform_get_irq(pdev, 0);
0184     if (axi->irq < 0)
0185         return axi->irq;
0186 
0187     ret = devm_request_irq(axi->dev, axi->irq, bt1_axi_isr, IRQF_SHARED,
0188                    "bt1-axi", axi);
0189     if (ret)
0190         dev_err(axi->dev, "Couldn't request AXI EHB IRQ\n");
0191 
0192     return ret;
0193 }
0194 
0195 static ssize_t count_show(struct device *dev,
0196               struct device_attribute *attr, char *buf)
0197 {
0198     struct bt1_axi *axi = dev_get_drvdata(dev);
0199 
0200     return scnprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&axi->count));
0201 }
0202 static DEVICE_ATTR_RO(count);
0203 
0204 static ssize_t inject_error_show(struct device *dev,
0205                  struct device_attribute *attr, char *buf)
0206 {
0207     return scnprintf(buf, PAGE_SIZE, "Error injection: bus unaligned\n");
0208 }
0209 
0210 static ssize_t inject_error_store(struct device *dev,
0211                   struct device_attribute *attr,
0212                   const char *data, size_t count)
0213 {
0214     struct bt1_axi *axi = dev_get_drvdata(dev);
0215 
0216     /*
0217      * Performing unaligned read from the memory will cause the CM2 bus
0218      * error while unaligned writing - the AXI bus write error handled
0219      * by this driver.
0220      */
0221     if (sysfs_streq(data, "bus"))
0222         readb(axi->qos_regs);
0223     else if (sysfs_streq(data, "unaligned"))
0224         writeb(0, axi->qos_regs);
0225     else
0226         return -EINVAL;
0227 
0228     return count;
0229 }
0230 static DEVICE_ATTR_RW(inject_error);
0231 
0232 static struct attribute *bt1_axi_sysfs_attrs[] = {
0233     &dev_attr_count.attr,
0234     &dev_attr_inject_error.attr,
0235     NULL
0236 };
0237 ATTRIBUTE_GROUPS(bt1_axi_sysfs);
0238 
0239 static void bt1_axi_remove_sysfs(void *data)
0240 {
0241     struct bt1_axi *axi = data;
0242 
0243     device_remove_groups(axi->dev, bt1_axi_sysfs_groups);
0244 }
0245 
0246 static int bt1_axi_init_sysfs(struct bt1_axi *axi)
0247 {
0248     int ret;
0249 
0250     ret = device_add_groups(axi->dev, bt1_axi_sysfs_groups);
0251     if (ret) {
0252         dev_err(axi->dev, "Failed to add sysfs files group\n");
0253         return ret;
0254     }
0255 
0256     ret = devm_add_action_or_reset(axi->dev, bt1_axi_remove_sysfs, axi);
0257     if (ret)
0258         dev_err(axi->dev, "Can't add AXI EHB sysfs remove action\n");
0259 
0260     return ret;
0261 }
0262 
0263 static int bt1_axi_probe(struct platform_device *pdev)
0264 {
0265     struct bt1_axi *axi;
0266     int ret;
0267 
0268     axi = bt1_axi_create_data(pdev);
0269     if (IS_ERR(axi))
0270         return PTR_ERR(axi);
0271 
0272     ret = bt1_axi_request_regs(axi);
0273     if (ret)
0274         return ret;
0275 
0276     ret = bt1_axi_request_rst(axi);
0277     if (ret)
0278         return ret;
0279 
0280     ret = bt1_axi_request_clk(axi);
0281     if (ret)
0282         return ret;
0283 
0284     ret = bt1_axi_request_irq(axi);
0285     if (ret)
0286         return ret;
0287 
0288     ret = bt1_axi_init_sysfs(axi);
0289     if (ret)
0290         return ret;
0291 
0292     return 0;
0293 }
0294 
0295 static const struct of_device_id bt1_axi_of_match[] = {
0296     { .compatible = "baikal,bt1-axi" },
0297     { }
0298 };
0299 MODULE_DEVICE_TABLE(of, bt1_axi_of_match);
0300 
0301 static struct platform_driver bt1_axi_driver = {
0302     .probe = bt1_axi_probe,
0303     .driver = {
0304         .name = "bt1-axi",
0305         .of_match_table = bt1_axi_of_match
0306     }
0307 };
0308 module_platform_driver(bt1_axi_driver);
0309 
0310 MODULE_AUTHOR("Serge Semin <Sergey.Semin@baikalelectronics.ru>");
0311 MODULE_DESCRIPTION("Baikal-T1 AXI-bus driver");
0312 MODULE_LICENSE("GPL v2");