1 // SPDX-License-Identifier: GPL-2.0-only 2 3 /* SpacemiT reset controller driver - common implementation */ 4 5 #include <linux/container_of.h> 6 #include <linux/device.h> 7 #include <linux/module.h> 8 9 #include <soc/spacemit/ccu.h> 10 11 #include "reset-spacemit-common.h" 12 13 static int spacemit_reset_update(struct reset_controller_dev *rcdev, 14 unsigned long id, bool assert) 15 { 16 struct ccu_reset_controller *controller; 17 const struct ccu_reset_data *data; 18 u32 mask; 19 u32 val; 20 21 controller = container_of(rcdev, struct ccu_reset_controller, rcdev); 22 data = &controller->data->reset_data[id]; 23 mask = data->assert_mask | data->deassert_mask; 24 val = assert ? data->assert_mask : data->deassert_mask; 25 26 return regmap_update_bits(controller->regmap, data->offset, mask, val); 27 } 28 29 static int spacemit_reset_assert(struct reset_controller_dev *rcdev, 30 unsigned long id) 31 { 32 return spacemit_reset_update(rcdev, id, true); 33 } 34 35 static int spacemit_reset_deassert(struct reset_controller_dev *rcdev, 36 unsigned long id) 37 { 38 return spacemit_reset_update(rcdev, id, false); 39 } 40 41 static const struct reset_control_ops spacemit_reset_control_ops = { 42 .assert = spacemit_reset_assert, 43 .deassert = spacemit_reset_deassert, 44 }; 45 46 static int spacemit_reset_controller_register(struct device *dev, 47 struct ccu_reset_controller *controller) 48 { 49 struct reset_controller_dev *rcdev = &controller->rcdev; 50 51 rcdev->ops = &spacemit_reset_control_ops; 52 rcdev->owner = dev->driver->owner; 53 rcdev->of_node = dev->of_node; 54 rcdev->nr_resets = controller->data->count; 55 56 return devm_reset_controller_register(dev, &controller->rcdev); 57 } 58 59 int spacemit_reset_probe(struct auxiliary_device *adev, 60 const struct auxiliary_device_id *id) 61 { 62 struct spacemit_ccu_adev *rdev = to_spacemit_ccu_adev(adev); 63 struct ccu_reset_controller *controller; 64 struct device *dev = &adev->dev; 65 66 controller = devm_kzalloc(dev, sizeof(*controller), GFP_KERNEL); 67 if (!controller) 68 return -ENOMEM; 69 controller->data = (const struct ccu_reset_controller_data *)id->driver_data; 70 controller->regmap = rdev->regmap; 71 72 return spacemit_reset_controller_register(dev, controller); 73 } 74 EXPORT_SYMBOL_NS_GPL(spacemit_reset_probe, "RESET_SPACEMIT"); 75 76 MODULE_DESCRIPTION("SpacemiT reset controller driver - common code"); 77 MODULE_LICENSE("GPL"); 78