1*89c1e2daSStephen Warren /* 2*89c1e2daSStephen Warren * Copyright (c) 2016, NVIDIA CORPORATION. 3*89c1e2daSStephen Warren * 4*89c1e2daSStephen Warren * SPDX-License-Identifier: GPL-2.0 5*89c1e2daSStephen Warren */ 6*89c1e2daSStephen Warren 7*89c1e2daSStephen Warren #include <common.h> 8*89c1e2daSStephen Warren #include <dm.h> 9*89c1e2daSStephen Warren #include <fdtdec.h> 10*89c1e2daSStephen Warren #include <reset.h> 11*89c1e2daSStephen Warren #include <reset-uclass.h> 12*89c1e2daSStephen Warren 13*89c1e2daSStephen Warren DECLARE_GLOBAL_DATA_PTR; 14*89c1e2daSStephen Warren 15*89c1e2daSStephen Warren static inline struct reset_ops *reset_dev_ops(struct udevice *dev) 16*89c1e2daSStephen Warren { 17*89c1e2daSStephen Warren return (struct reset_ops *)dev->driver->ops; 18*89c1e2daSStephen Warren } 19*89c1e2daSStephen Warren 20*89c1e2daSStephen Warren static int reset_of_xlate_default(struct reset_ctl *reset_ctl, 21*89c1e2daSStephen Warren struct fdtdec_phandle_args *args) 22*89c1e2daSStephen Warren { 23*89c1e2daSStephen Warren debug("%s(reset_ctl=%p)\n", __func__, reset_ctl); 24*89c1e2daSStephen Warren 25*89c1e2daSStephen Warren if (args->args_count != 1) { 26*89c1e2daSStephen Warren debug("Invaild args_count: %d\n", args->args_count); 27*89c1e2daSStephen Warren return -EINVAL; 28*89c1e2daSStephen Warren } 29*89c1e2daSStephen Warren 30*89c1e2daSStephen Warren reset_ctl->id = args->args[0]; 31*89c1e2daSStephen Warren 32*89c1e2daSStephen Warren return 0; 33*89c1e2daSStephen Warren } 34*89c1e2daSStephen Warren 35*89c1e2daSStephen Warren int reset_get_by_index(struct udevice *dev, int index, 36*89c1e2daSStephen Warren struct reset_ctl *reset_ctl) 37*89c1e2daSStephen Warren { 38*89c1e2daSStephen Warren struct fdtdec_phandle_args args; 39*89c1e2daSStephen Warren int ret; 40*89c1e2daSStephen Warren struct udevice *dev_reset; 41*89c1e2daSStephen Warren struct reset_ops *ops; 42*89c1e2daSStephen Warren 43*89c1e2daSStephen Warren debug("%s(dev=%p, index=%d, reset_ctl=%p)\n", __func__, dev, index, 44*89c1e2daSStephen Warren reset_ctl); 45*89c1e2daSStephen Warren 46*89c1e2daSStephen Warren ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev->of_offset, 47*89c1e2daSStephen Warren "resets", "#reset-cells", 0, 48*89c1e2daSStephen Warren index, &args); 49*89c1e2daSStephen Warren if (ret) { 50*89c1e2daSStephen Warren debug("%s: fdtdec_parse_phandle_with_args failed: %d\n", 51*89c1e2daSStephen Warren __func__, ret); 52*89c1e2daSStephen Warren return ret; 53*89c1e2daSStephen Warren } 54*89c1e2daSStephen Warren 55*89c1e2daSStephen Warren ret = uclass_get_device_by_of_offset(UCLASS_RESET, args.node, 56*89c1e2daSStephen Warren &dev_reset); 57*89c1e2daSStephen Warren if (ret) { 58*89c1e2daSStephen Warren debug("%s: uclass_get_device_by_of_offset failed: %d\n", 59*89c1e2daSStephen Warren __func__, ret); 60*89c1e2daSStephen Warren return ret; 61*89c1e2daSStephen Warren } 62*89c1e2daSStephen Warren ops = reset_dev_ops(dev_reset); 63*89c1e2daSStephen Warren 64*89c1e2daSStephen Warren reset_ctl->dev = dev_reset; 65*89c1e2daSStephen Warren if (ops->of_xlate) 66*89c1e2daSStephen Warren ret = ops->of_xlate(reset_ctl, &args); 67*89c1e2daSStephen Warren else 68*89c1e2daSStephen Warren ret = reset_of_xlate_default(reset_ctl, &args); 69*89c1e2daSStephen Warren if (ret) { 70*89c1e2daSStephen Warren debug("of_xlate() failed: %d\n", ret); 71*89c1e2daSStephen Warren return ret; 72*89c1e2daSStephen Warren } 73*89c1e2daSStephen Warren 74*89c1e2daSStephen Warren ret = ops->request(reset_ctl); 75*89c1e2daSStephen Warren if (ret) { 76*89c1e2daSStephen Warren debug("ops->request() failed: %d\n", ret); 77*89c1e2daSStephen Warren return ret; 78*89c1e2daSStephen Warren } 79*89c1e2daSStephen Warren 80*89c1e2daSStephen Warren return 0; 81*89c1e2daSStephen Warren } 82*89c1e2daSStephen Warren 83*89c1e2daSStephen Warren int reset_get_by_name(struct udevice *dev, const char *name, 84*89c1e2daSStephen Warren struct reset_ctl *reset_ctl) 85*89c1e2daSStephen Warren { 86*89c1e2daSStephen Warren int index; 87*89c1e2daSStephen Warren 88*89c1e2daSStephen Warren debug("%s(dev=%p, name=%s, reset_ctl=%p)\n", __func__, dev, name, 89*89c1e2daSStephen Warren reset_ctl); 90*89c1e2daSStephen Warren 91*89c1e2daSStephen Warren index = fdt_find_string(gd->fdt_blob, dev->of_offset, "reset-names", 92*89c1e2daSStephen Warren name); 93*89c1e2daSStephen Warren if (index < 0) { 94*89c1e2daSStephen Warren debug("fdt_find_string() failed: %d\n", index); 95*89c1e2daSStephen Warren return index; 96*89c1e2daSStephen Warren } 97*89c1e2daSStephen Warren 98*89c1e2daSStephen Warren return reset_get_by_index(dev, index, reset_ctl); 99*89c1e2daSStephen Warren } 100*89c1e2daSStephen Warren 101*89c1e2daSStephen Warren int reset_free(struct reset_ctl *reset_ctl) 102*89c1e2daSStephen Warren { 103*89c1e2daSStephen Warren struct reset_ops *ops = reset_dev_ops(reset_ctl->dev); 104*89c1e2daSStephen Warren 105*89c1e2daSStephen Warren debug("%s(reset_ctl=%p)\n", __func__, reset_ctl); 106*89c1e2daSStephen Warren 107*89c1e2daSStephen Warren return ops->free(reset_ctl); 108*89c1e2daSStephen Warren } 109*89c1e2daSStephen Warren 110*89c1e2daSStephen Warren int reset_assert(struct reset_ctl *reset_ctl) 111*89c1e2daSStephen Warren { 112*89c1e2daSStephen Warren struct reset_ops *ops = reset_dev_ops(reset_ctl->dev); 113*89c1e2daSStephen Warren 114*89c1e2daSStephen Warren debug("%s(reset_ctl=%p)\n", __func__, reset_ctl); 115*89c1e2daSStephen Warren 116*89c1e2daSStephen Warren return ops->rst_assert(reset_ctl); 117*89c1e2daSStephen Warren } 118*89c1e2daSStephen Warren 119*89c1e2daSStephen Warren int reset_deassert(struct reset_ctl *reset_ctl) 120*89c1e2daSStephen Warren { 121*89c1e2daSStephen Warren struct reset_ops *ops = reset_dev_ops(reset_ctl->dev); 122*89c1e2daSStephen Warren 123*89c1e2daSStephen Warren debug("%s(reset_ctl=%p)\n", __func__, reset_ctl); 124*89c1e2daSStephen Warren 125*89c1e2daSStephen Warren return ops->rst_deassert(reset_ctl); 126*89c1e2daSStephen Warren } 127*89c1e2daSStephen Warren 128*89c1e2daSStephen Warren UCLASS_DRIVER(reset) = { 129*89c1e2daSStephen Warren .id = UCLASS_RESET, 130*89c1e2daSStephen Warren .name = "reset", 131*89c1e2daSStephen Warren }; 132