misc: k3_esm: Add support for Texas Instruments K3 ESM driver
[platform/kernel/u-boot.git] / drivers / misc / k3_esm.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Texas Instruments' K3 Error Signalling Module driver
4  *
5  * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
6  *      Tero Kristo <t-kristo@ti.com>
7  *
8  */
9
10 #include <common.h>
11 #include <dm.h>
12 #include <errno.h>
13 #include <asm/io.h>
14 #include <dm/device_compat.h>
15
16 #define ESM_SFT_RST                     0x0c
17 #define ESM_SFT_RST_KEY                 0x0f
18
19 #define ESM_STS(i)                      (0x404 + (i) / 32 * 0x20)
20 #define ESM_PIN_EN_SET_OFFSET(i)        (0x414 + (i) / 32 * 0x20)
21 #define ESM_PIN_MASK(i)                 BIT((i) & 0x1f)
22
23 static void esm_pin_enable(void __iomem *base, int pin)
24 {
25         /* Enable event */
26         writel(ESM_PIN_MASK(pin), base + ESM_PIN_EN_SET_OFFSET(pin));
27 }
28
29 /**
30  * k3_esm_probe: configures ESM based on DT data
31  *
32  * Parses ESM info from device tree, and configures the module accordingly.
33  */
34 static int k3_esm_probe(struct udevice *dev)
35 {
36         int ret;
37         void __iomem *base;
38         int num_pins;
39         u32 *pins;
40         int i;
41
42         base = dev_remap_addr_index(dev, 0);
43         if (!base)
44                 return -ENODEV;
45
46         num_pins = dev_read_size(dev, "ti,esm-pins");
47         if (num_pins < 0) {
48                 dev_err(dev, "ti,esm-pins property missing or invalid: %d\n",
49                         num_pins);
50                 return num_pins;
51         }
52
53         num_pins /= sizeof(u32);
54
55         pins = kmalloc(num_pins * sizeof(u32), __GFP_ZERO);
56         if (!pins)
57                 return -ENOMEM;
58
59         ret = dev_read_u32_array(dev, "ti,esm-pins", pins, num_pins);
60         if (ret < 0) {
61                 dev_err(dev, "failed to read ti,esm-pins property: %d\n",
62                         ret);
63                 goto free_pins;
64         }
65
66         /* Clear any pending events */
67         writel(ESM_SFT_RST_KEY, base + ESM_SFT_RST);
68
69         for (i = 0; i < num_pins; i++)
70                 esm_pin_enable(base, pins[i]);
71
72 free_pins:
73         kfree(pins);
74         return ret;
75 }
76
77 static const struct udevice_id k3_esm_ids[] = {
78         { .compatible = "ti,j721e-esm" },
79         {}
80 };
81
82 U_BOOT_DRIVER(k3_esm) = {
83         .name = "k3_esm",
84         .of_match = k3_esm_ids,
85         .id = UCLASS_MISC,
86         .probe = k3_esm_probe,
87 };