14af34b57SMaxime Ripard /* 24af34b57SMaxime Ripard * Allwinner SoCs SRAM Controller Driver 34af34b57SMaxime Ripard * 44af34b57SMaxime Ripard * Copyright (C) 2015 Maxime Ripard 54af34b57SMaxime Ripard * 64af34b57SMaxime Ripard * Author: Maxime Ripard <maxime.ripard@free-electrons.com> 74af34b57SMaxime Ripard * 84af34b57SMaxime Ripard * This file is licensed under the terms of the GNU General Public 94af34b57SMaxime Ripard * License version 2. This program is licensed "as is" without any 104af34b57SMaxime Ripard * warranty of any kind, whether express or implied. 114af34b57SMaxime Ripard */ 124af34b57SMaxime Ripard 134af34b57SMaxime Ripard #include <linux/debugfs.h> 144af34b57SMaxime Ripard #include <linux/io.h> 154af34b57SMaxime Ripard #include <linux/module.h> 164af34b57SMaxime Ripard #include <linux/of.h> 174af34b57SMaxime Ripard #include <linux/of_address.h> 184af34b57SMaxime Ripard #include <linux/of_device.h> 194af34b57SMaxime Ripard #include <linux/platform_device.h> 205828729bSIcenowy Zheng #include <linux/regmap.h> 214af34b57SMaxime Ripard 224af34b57SMaxime Ripard #include <linux/soc/sunxi/sunxi_sram.h> 234af34b57SMaxime Ripard 244af34b57SMaxime Ripard struct sunxi_sram_func { 254af34b57SMaxime Ripard char *func; 264af34b57SMaxime Ripard u8 val; 278fed2ce9SIcenowy Zheng u32 reg_val; 284af34b57SMaxime Ripard }; 294af34b57SMaxime Ripard 304af34b57SMaxime Ripard struct sunxi_sram_data { 314af34b57SMaxime Ripard char *name; 324af34b57SMaxime Ripard u8 reg; 334af34b57SMaxime Ripard u8 offset; 344af34b57SMaxime Ripard u8 width; 354af34b57SMaxime Ripard struct sunxi_sram_func *func; 364af34b57SMaxime Ripard struct list_head list; 374af34b57SMaxime Ripard }; 384af34b57SMaxime Ripard 394af34b57SMaxime Ripard struct sunxi_sram_desc { 404af34b57SMaxime Ripard struct sunxi_sram_data data; 414af34b57SMaxime Ripard bool claimed; 424af34b57SMaxime Ripard }; 434af34b57SMaxime Ripard 448fed2ce9SIcenowy Zheng #define SUNXI_SRAM_MAP(_reg_val, _val, _func) \ 454af34b57SMaxime Ripard { \ 464af34b57SMaxime Ripard .func = _func, \ 474af34b57SMaxime Ripard .val = _val, \ 488fed2ce9SIcenowy Zheng .reg_val = _reg_val, \ 494af34b57SMaxime Ripard } 504af34b57SMaxime Ripard 514af34b57SMaxime Ripard #define SUNXI_SRAM_DATA(_name, _reg, _off, _width, ...) \ 524af34b57SMaxime Ripard { \ 534af34b57SMaxime Ripard .name = _name, \ 544af34b57SMaxime Ripard .reg = _reg, \ 554af34b57SMaxime Ripard .offset = _off, \ 564af34b57SMaxime Ripard .width = _width, \ 574af34b57SMaxime Ripard .func = (struct sunxi_sram_func[]){ \ 584af34b57SMaxime Ripard __VA_ARGS__, { } }, \ 594af34b57SMaxime Ripard } 604af34b57SMaxime Ripard 614af34b57SMaxime Ripard static struct sunxi_sram_desc sun4i_a10_sram_a3_a4 = { 624af34b57SMaxime Ripard .data = SUNXI_SRAM_DATA("A3-A4", 0x4, 0x4, 2, 638fed2ce9SIcenowy Zheng SUNXI_SRAM_MAP(0, 0, "cpu"), 648fed2ce9SIcenowy Zheng SUNXI_SRAM_MAP(1, 1, "emac")), 654af34b57SMaxime Ripard }; 664af34b57SMaxime Ripard 675fdec16bSMaxime Ripard static struct sunxi_sram_desc sun4i_a10_sram_c1 = { 685fdec16bSMaxime Ripard .data = SUNXI_SRAM_DATA("C1", 0x0, 0x0, 31, 695fdec16bSMaxime Ripard SUNXI_SRAM_MAP(0, 0, "cpu"), 705fdec16bSMaxime Ripard SUNXI_SRAM_MAP(0x7fffffff, 1, "ve")), 715fdec16bSMaxime Ripard }; 725fdec16bSMaxime Ripard 734af34b57SMaxime Ripard static struct sunxi_sram_desc sun4i_a10_sram_d = { 744af34b57SMaxime Ripard .data = SUNXI_SRAM_DATA("D", 0x4, 0x0, 1, 758fed2ce9SIcenowy Zheng SUNXI_SRAM_MAP(0, 0, "cpu"), 768fed2ce9SIcenowy Zheng SUNXI_SRAM_MAP(1, 1, "usb-otg")), 774af34b57SMaxime Ripard }; 784af34b57SMaxime Ripard 795e4fb642SIcenowy Zheng static struct sunxi_sram_desc sun50i_a64_sram_c = { 805e4fb642SIcenowy Zheng .data = SUNXI_SRAM_DATA("C", 0x4, 24, 1, 81e3c95edbSSamuel Holland SUNXI_SRAM_MAP(1, 0, "cpu"), 82e3c95edbSSamuel Holland SUNXI_SRAM_MAP(0, 1, "de2")), 835e4fb642SIcenowy Zheng }; 845e4fb642SIcenowy Zheng 854af34b57SMaxime Ripard static const struct of_device_id sunxi_sram_dt_ids[] = { 864af34b57SMaxime Ripard { 874af34b57SMaxime Ripard .compatible = "allwinner,sun4i-a10-sram-a3-a4", 884af34b57SMaxime Ripard .data = &sun4i_a10_sram_a3_a4.data, 894af34b57SMaxime Ripard }, 904af34b57SMaxime Ripard { 915fdec16bSMaxime Ripard .compatible = "allwinner,sun4i-a10-sram-c1", 925fdec16bSMaxime Ripard .data = &sun4i_a10_sram_c1.data, 935fdec16bSMaxime Ripard }, 945fdec16bSMaxime Ripard { 954af34b57SMaxime Ripard .compatible = "allwinner,sun4i-a10-sram-d", 964af34b57SMaxime Ripard .data = &sun4i_a10_sram_d.data, 974af34b57SMaxime Ripard }, 985e4fb642SIcenowy Zheng { 995e4fb642SIcenowy Zheng .compatible = "allwinner,sun50i-a64-sram-c", 1005e4fb642SIcenowy Zheng .data = &sun50i_a64_sram_c.data, 1015e4fb642SIcenowy Zheng }, 1024af34b57SMaxime Ripard {} 1034af34b57SMaxime Ripard }; 1044af34b57SMaxime Ripard 1054af34b57SMaxime Ripard static struct device *sram_dev; 1064af34b57SMaxime Ripard static LIST_HEAD(claimed_sram); 1074af34b57SMaxime Ripard static DEFINE_SPINLOCK(sram_lock); 1084af34b57SMaxime Ripard static void __iomem *base; 1094af34b57SMaxime Ripard 1104af34b57SMaxime Ripard static int sunxi_sram_show(struct seq_file *s, void *data) 1114af34b57SMaxime Ripard { 1124af34b57SMaxime Ripard struct device_node *sram_node, *section_node; 1134af34b57SMaxime Ripard const struct sunxi_sram_data *sram_data; 1144af34b57SMaxime Ripard const struct of_device_id *match; 1154af34b57SMaxime Ripard struct sunxi_sram_func *func; 1164af34b57SMaxime Ripard const __be32 *sram_addr_p, *section_addr_p; 1174af34b57SMaxime Ripard u32 val; 1184af34b57SMaxime Ripard 1194af34b57SMaxime Ripard seq_puts(s, "Allwinner sunXi SRAM\n"); 1204af34b57SMaxime Ripard seq_puts(s, "--------------------\n\n"); 1214af34b57SMaxime Ripard 1224af34b57SMaxime Ripard for_each_child_of_node(sram_dev->of_node, sram_node) { 1234af34b57SMaxime Ripard sram_addr_p = of_get_address(sram_node, 0, NULL, NULL); 1244af34b57SMaxime Ripard 1254af34b57SMaxime Ripard seq_printf(s, "sram@%08x\n", 1264af34b57SMaxime Ripard be32_to_cpu(*sram_addr_p)); 1274af34b57SMaxime Ripard 1284af34b57SMaxime Ripard for_each_child_of_node(sram_node, section_node) { 1294af34b57SMaxime Ripard match = of_match_node(sunxi_sram_dt_ids, section_node); 1304af34b57SMaxime Ripard if (!match) 1314af34b57SMaxime Ripard continue; 1324af34b57SMaxime Ripard sram_data = match->data; 1334af34b57SMaxime Ripard 1344af34b57SMaxime Ripard section_addr_p = of_get_address(section_node, 0, 1354af34b57SMaxime Ripard NULL, NULL); 1364af34b57SMaxime Ripard 1374af34b57SMaxime Ripard seq_printf(s, "\tsection@%04x\t(%s)\n", 1384af34b57SMaxime Ripard be32_to_cpu(*section_addr_p), 1394af34b57SMaxime Ripard sram_data->name); 1404af34b57SMaxime Ripard 1414af34b57SMaxime Ripard val = readl(base + sram_data->reg); 1424af34b57SMaxime Ripard val >>= sram_data->offset; 143febe6569SJens Kuske val &= GENMASK(sram_data->width - 1, 0); 1444af34b57SMaxime Ripard 1454af34b57SMaxime Ripard for (func = sram_data->func; func->func; func++) { 1464af34b57SMaxime Ripard seq_printf(s, "\t\t%s%c\n", func->func, 1478fed2ce9SIcenowy Zheng func->reg_val == val ? 1488fed2ce9SIcenowy Zheng '*' : ' '); 1494af34b57SMaxime Ripard } 1504af34b57SMaxime Ripard } 1514af34b57SMaxime Ripard 1524af34b57SMaxime Ripard seq_puts(s, "\n"); 1534af34b57SMaxime Ripard } 1544af34b57SMaxime Ripard 1554af34b57SMaxime Ripard return 0; 1564af34b57SMaxime Ripard } 1574af34b57SMaxime Ripard 1582a8c9f12SYangtao Li DEFINE_SHOW_ATTRIBUTE(sunxi_sram); 1594af34b57SMaxime Ripard 1604af34b57SMaxime Ripard static inline struct sunxi_sram_desc *to_sram_desc(const struct sunxi_sram_data *data) 1614af34b57SMaxime Ripard { 1624af34b57SMaxime Ripard return container_of(data, struct sunxi_sram_desc, data); 1634af34b57SMaxime Ripard } 1644af34b57SMaxime Ripard 1654af34b57SMaxime Ripard static const struct sunxi_sram_data *sunxi_sram_of_parse(struct device_node *node, 1668fed2ce9SIcenowy Zheng unsigned int *reg_value) 1674af34b57SMaxime Ripard { 1684af34b57SMaxime Ripard const struct of_device_id *match; 1698fed2ce9SIcenowy Zheng const struct sunxi_sram_data *data; 1708fed2ce9SIcenowy Zheng struct sunxi_sram_func *func; 1714af34b57SMaxime Ripard struct of_phandle_args args; 1728fed2ce9SIcenowy Zheng u8 val; 1734af34b57SMaxime Ripard int ret; 1744af34b57SMaxime Ripard 1754af34b57SMaxime Ripard ret = of_parse_phandle_with_fixed_args(node, "allwinner,sram", 1, 0, 1764af34b57SMaxime Ripard &args); 1774af34b57SMaxime Ripard if (ret) 1784af34b57SMaxime Ripard return ERR_PTR(ret); 1794af34b57SMaxime Ripard 1804af34b57SMaxime Ripard if (!of_device_is_available(args.np)) { 1814af34b57SMaxime Ripard ret = -EBUSY; 1824af34b57SMaxime Ripard goto err; 1834af34b57SMaxime Ripard } 1844af34b57SMaxime Ripard 1858fed2ce9SIcenowy Zheng val = args.args[0]; 1864af34b57SMaxime Ripard 1874af34b57SMaxime Ripard match = of_match_node(sunxi_sram_dt_ids, args.np); 1884af34b57SMaxime Ripard if (!match) { 1894af34b57SMaxime Ripard ret = -EINVAL; 1904af34b57SMaxime Ripard goto err; 1914af34b57SMaxime Ripard } 1924af34b57SMaxime Ripard 1938fed2ce9SIcenowy Zheng data = match->data; 1948fed2ce9SIcenowy Zheng if (!data) { 1958fed2ce9SIcenowy Zheng ret = -EINVAL; 1968fed2ce9SIcenowy Zheng goto err; 1971893a2d5SJason Yan } 1988fed2ce9SIcenowy Zheng 1998fed2ce9SIcenowy Zheng for (func = data->func; func->func; func++) { 2008fed2ce9SIcenowy Zheng if (val == func->val) { 2018fed2ce9SIcenowy Zheng if (reg_value) 2028fed2ce9SIcenowy Zheng *reg_value = func->reg_val; 2038fed2ce9SIcenowy Zheng 2048fed2ce9SIcenowy Zheng break; 2058fed2ce9SIcenowy Zheng } 2068fed2ce9SIcenowy Zheng } 2078fed2ce9SIcenowy Zheng 2088fed2ce9SIcenowy Zheng if (!func->func) { 2098fed2ce9SIcenowy Zheng ret = -EINVAL; 2108fed2ce9SIcenowy Zheng goto err; 2118fed2ce9SIcenowy Zheng } 2128fed2ce9SIcenowy Zheng 2134af34b57SMaxime Ripard of_node_put(args.np); 2144af34b57SMaxime Ripard return match->data; 2154af34b57SMaxime Ripard 2164af34b57SMaxime Ripard err: 2174af34b57SMaxime Ripard of_node_put(args.np); 2184af34b57SMaxime Ripard return ERR_PTR(ret); 2194af34b57SMaxime Ripard } 2204af34b57SMaxime Ripard 2214af34b57SMaxime Ripard int sunxi_sram_claim(struct device *dev) 2224af34b57SMaxime Ripard { 2234af34b57SMaxime Ripard const struct sunxi_sram_data *sram_data; 2244af34b57SMaxime Ripard struct sunxi_sram_desc *sram_desc; 2254af34b57SMaxime Ripard unsigned int device; 2264af34b57SMaxime Ripard u32 val, mask; 2274af34b57SMaxime Ripard 2284af34b57SMaxime Ripard if (IS_ERR(base)) 2292262a65fSIcenowy Zheng return PTR_ERR(base); 2302262a65fSIcenowy Zheng 2312262a65fSIcenowy Zheng if (!base) 2324af34b57SMaxime Ripard return -EPROBE_DEFER; 2334af34b57SMaxime Ripard 2344af34b57SMaxime Ripard if (!dev || !dev->of_node) 2354af34b57SMaxime Ripard return -EINVAL; 2364af34b57SMaxime Ripard 2374af34b57SMaxime Ripard sram_data = sunxi_sram_of_parse(dev->of_node, &device); 2384af34b57SMaxime Ripard if (IS_ERR(sram_data)) 2394af34b57SMaxime Ripard return PTR_ERR(sram_data); 2404af34b57SMaxime Ripard 2414af34b57SMaxime Ripard sram_desc = to_sram_desc(sram_data); 2424af34b57SMaxime Ripard 2434af34b57SMaxime Ripard spin_lock(&sram_lock); 2444af34b57SMaxime Ripard 2454af34b57SMaxime Ripard if (sram_desc->claimed) { 2464af34b57SMaxime Ripard spin_unlock(&sram_lock); 2474af34b57SMaxime Ripard return -EBUSY; 2484af34b57SMaxime Ripard } 2494af34b57SMaxime Ripard 250febe6569SJens Kuske mask = GENMASK(sram_data->offset + sram_data->width - 1, 251febe6569SJens Kuske sram_data->offset); 2524af34b57SMaxime Ripard val = readl(base + sram_data->reg); 2534af34b57SMaxime Ripard val &= ~mask; 2544af34b57SMaxime Ripard writel(val | ((device << sram_data->offset) & mask), 2554af34b57SMaxime Ripard base + sram_data->reg); 2564af34b57SMaxime Ripard 257fd362baaSSamuel Holland sram_desc->claimed = true; 2584af34b57SMaxime Ripard spin_unlock(&sram_lock); 2594af34b57SMaxime Ripard 2604af34b57SMaxime Ripard return 0; 2614af34b57SMaxime Ripard } 2624af34b57SMaxime Ripard EXPORT_SYMBOL(sunxi_sram_claim); 2634af34b57SMaxime Ripard 264*460d9cb6SSamuel Holland void sunxi_sram_release(struct device *dev) 2654af34b57SMaxime Ripard { 2664af34b57SMaxime Ripard const struct sunxi_sram_data *sram_data; 2674af34b57SMaxime Ripard struct sunxi_sram_desc *sram_desc; 2684af34b57SMaxime Ripard 2694af34b57SMaxime Ripard if (!dev || !dev->of_node) 270*460d9cb6SSamuel Holland return; 2714af34b57SMaxime Ripard 2724af34b57SMaxime Ripard sram_data = sunxi_sram_of_parse(dev->of_node, NULL); 2734af34b57SMaxime Ripard if (IS_ERR(sram_data)) 274*460d9cb6SSamuel Holland return; 2754af34b57SMaxime Ripard 2764af34b57SMaxime Ripard sram_desc = to_sram_desc(sram_data); 2774af34b57SMaxime Ripard 2784af34b57SMaxime Ripard spin_lock(&sram_lock); 2794af34b57SMaxime Ripard sram_desc->claimed = false; 2804af34b57SMaxime Ripard spin_unlock(&sram_lock); 2814af34b57SMaxime Ripard } 2824af34b57SMaxime Ripard EXPORT_SYMBOL(sunxi_sram_release); 2834af34b57SMaxime Ripard 2845828729bSIcenowy Zheng struct sunxi_sramc_variant { 2859117d0c9SAndre Przywara int num_emac_clocks; 2865828729bSIcenowy Zheng }; 2875828729bSIcenowy Zheng 2885828729bSIcenowy Zheng static const struct sunxi_sramc_variant sun4i_a10_sramc_variant = { 2895828729bSIcenowy Zheng /* Nothing special */ 2905828729bSIcenowy Zheng }; 2915828729bSIcenowy Zheng 29215e53723SPaul Kocialkowski static const struct sunxi_sramc_variant sun8i_h3_sramc_variant = { 2939117d0c9SAndre Przywara .num_emac_clocks = 1, 29415e53723SPaul Kocialkowski }; 29515e53723SPaul Kocialkowski 2965828729bSIcenowy Zheng static const struct sunxi_sramc_variant sun50i_a64_sramc_variant = { 2979117d0c9SAndre Przywara .num_emac_clocks = 1, 2989117d0c9SAndre Przywara }; 2999117d0c9SAndre Przywara 3009117d0c9SAndre Przywara static const struct sunxi_sramc_variant sun50i_h616_sramc_variant = { 3019117d0c9SAndre Przywara .num_emac_clocks = 2, 3025828729bSIcenowy Zheng }; 3035828729bSIcenowy Zheng 3045828729bSIcenowy Zheng #define SUNXI_SRAM_EMAC_CLOCK_REG 0x30 3055828729bSIcenowy Zheng static bool sunxi_sram_regmap_accessible_reg(struct device *dev, 3065828729bSIcenowy Zheng unsigned int reg) 3075828729bSIcenowy Zheng { 3089117d0c9SAndre Przywara const struct sunxi_sramc_variant *variant; 3099117d0c9SAndre Przywara 3109117d0c9SAndre Przywara variant = of_device_get_match_data(dev); 3119117d0c9SAndre Przywara 3129117d0c9SAndre Przywara if (reg < SUNXI_SRAM_EMAC_CLOCK_REG) 3135828729bSIcenowy Zheng return false; 3149117d0c9SAndre Przywara if (reg > SUNXI_SRAM_EMAC_CLOCK_REG + variant->num_emac_clocks * 4) 3159117d0c9SAndre Przywara return false; 3169117d0c9SAndre Przywara 3179117d0c9SAndre Przywara return true; 3185828729bSIcenowy Zheng } 3195828729bSIcenowy Zheng 3205828729bSIcenowy Zheng static struct regmap_config sunxi_sram_emac_clock_regmap = { 3215828729bSIcenowy Zheng .reg_bits = 32, 3225828729bSIcenowy Zheng .val_bits = 32, 3235828729bSIcenowy Zheng .reg_stride = 4, 3245828729bSIcenowy Zheng /* last defined register */ 3259117d0c9SAndre Przywara .max_register = SUNXI_SRAM_EMAC_CLOCK_REG + 4, 3265828729bSIcenowy Zheng /* other devices have no business accessing other registers */ 3275828729bSIcenowy Zheng .readable_reg = sunxi_sram_regmap_accessible_reg, 3285828729bSIcenowy Zheng .writeable_reg = sunxi_sram_regmap_accessible_reg, 3295828729bSIcenowy Zheng }; 3305828729bSIcenowy Zheng 33190e10a1fSSamuel Holland static int __init sunxi_sram_probe(struct platform_device *pdev) 3324af34b57SMaxime Ripard { 3335828729bSIcenowy Zheng struct regmap *emac_clock; 3345828729bSIcenowy Zheng const struct sunxi_sramc_variant *variant; 33549fad91aSSamuel Holland struct device *dev = &pdev->dev; 3364af34b57SMaxime Ripard 3374af34b57SMaxime Ripard sram_dev = &pdev->dev; 3384af34b57SMaxime Ripard 3395828729bSIcenowy Zheng variant = of_device_get_match_data(&pdev->dev); 3405828729bSIcenowy Zheng if (!variant) 3415828729bSIcenowy Zheng return -EINVAL; 3425828729bSIcenowy Zheng 3431f3753a5SCai Huoqing base = devm_platform_ioremap_resource(pdev, 0); 3444af34b57SMaxime Ripard if (IS_ERR(base)) 3454af34b57SMaxime Ripard return PTR_ERR(base); 3464af34b57SMaxime Ripard 3479117d0c9SAndre Przywara if (variant->num_emac_clocks > 0) { 3485828729bSIcenowy Zheng emac_clock = devm_regmap_init_mmio(&pdev->dev, base, 3495828729bSIcenowy Zheng &sunxi_sram_emac_clock_regmap); 3505828729bSIcenowy Zheng 3515828729bSIcenowy Zheng if (IS_ERR(emac_clock)) 3525828729bSIcenowy Zheng return PTR_ERR(emac_clock); 3535828729bSIcenowy Zheng } 3545828729bSIcenowy Zheng 35549fad91aSSamuel Holland of_platform_populate(dev->of_node, NULL, NULL, dev); 35649fad91aSSamuel Holland 35749fad91aSSamuel Holland debugfs_create_file("sram", 0444, NULL, NULL, &sunxi_sram_fops); 35849fad91aSSamuel Holland 3594af34b57SMaxime Ripard return 0; 3604af34b57SMaxime Ripard } 3614af34b57SMaxime Ripard 3624af34b57SMaxime Ripard static const struct of_device_id sunxi_sram_dt_match[] = { 3635828729bSIcenowy Zheng { 3645828729bSIcenowy Zheng .compatible = "allwinner,sun4i-a10-sram-controller", 3655828729bSIcenowy Zheng .data = &sun4i_a10_sramc_variant, 3665828729bSIcenowy Zheng }, 3675828729bSIcenowy Zheng { 368acc26f59SPaul Kocialkowski .compatible = "allwinner,sun4i-a10-system-control", 369acc26f59SPaul Kocialkowski .data = &sun4i_a10_sramc_variant, 370acc26f59SPaul Kocialkowski }, 371acc26f59SPaul Kocialkowski { 3727377330aSMaxime Ripard .compatible = "allwinner,sun5i-a13-system-control", 3737377330aSMaxime Ripard .data = &sun4i_a10_sramc_variant, 3747377330aSMaxime Ripard }, 3757377330aSMaxime Ripard { 3767377330aSMaxime Ripard .compatible = "allwinner,sun8i-a23-system-control", 3777377330aSMaxime Ripard .data = &sun4i_a10_sramc_variant, 3787377330aSMaxime Ripard }, 3797377330aSMaxime Ripard { 3807377330aSMaxime Ripard .compatible = "allwinner,sun8i-h3-system-control", 38115e53723SPaul Kocialkowski .data = &sun8i_h3_sramc_variant, 3827377330aSMaxime Ripard }, 3837377330aSMaxime Ripard { 3845828729bSIcenowy Zheng .compatible = "allwinner,sun50i-a64-sram-controller", 3855828729bSIcenowy Zheng .data = &sun50i_a64_sramc_variant, 3865828729bSIcenowy Zheng }, 387ede18ae3SChen-Yu Tsai { 388ede18ae3SChen-Yu Tsai .compatible = "allwinner,sun50i-a64-system-control", 389ede18ae3SChen-Yu Tsai .data = &sun50i_a64_sramc_variant, 390ede18ae3SChen-Yu Tsai }, 391c7739268SPaul Kocialkowski { 392c7739268SPaul Kocialkowski .compatible = "allwinner,sun50i-h5-system-control", 393c7739268SPaul Kocialkowski .data = &sun50i_a64_sramc_variant, 394c7739268SPaul Kocialkowski }, 3959117d0c9SAndre Przywara { 3969117d0c9SAndre Przywara .compatible = "allwinner,sun50i-h616-system-control", 3979117d0c9SAndre Przywara .data = &sun50i_h616_sramc_variant, 3989117d0c9SAndre Przywara }, 3994af34b57SMaxime Ripard { }, 4004af34b57SMaxime Ripard }; 4014af34b57SMaxime Ripard MODULE_DEVICE_TABLE(of, sunxi_sram_dt_match); 4024af34b57SMaxime Ripard 4034af34b57SMaxime Ripard static struct platform_driver sunxi_sram_driver = { 4044af34b57SMaxime Ripard .driver = { 4054af34b57SMaxime Ripard .name = "sunxi-sram", 4064af34b57SMaxime Ripard .of_match_table = sunxi_sram_dt_match, 4074af34b57SMaxime Ripard }, 4084af34b57SMaxime Ripard }; 40990e10a1fSSamuel Holland builtin_platform_driver_probe(sunxi_sram_driver, sunxi_sram_probe); 4104af34b57SMaxime Ripard 4114af34b57SMaxime Ripard MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>"); 4124af34b57SMaxime Ripard MODULE_DESCRIPTION("Allwinner sunXi SRAM Controller Driver"); 4134af34b57SMaxime Ripard MODULE_LICENSE("GPL"); 414