^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Turris Mox module configuration bus driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2019 Marek Behun <marek.behun@nic.cz>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <dt-bindings/bus/moxtet.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/debugfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/moxtet.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/of_irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/spi/spi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * @name: module name for sysfs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * @hwirq_base: base index for IRQ for this module (-1 if no IRQs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * @nirqs: how many interrupts does the shift register provide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * @desc: module description for kernel log
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) static const struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) int hwirq_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) int nirqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) const char *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) } mox_module_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) /* do not change order of this array! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) { NULL, 0, 0, NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) { "sfp", -1, 0, "MOX D (SFP cage)" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) { "pci", MOXTET_IRQ_PCI, 1, "MOX B (Mini-PCIe)" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) { "topaz", MOXTET_IRQ_TOPAZ, 1, "MOX C (4 port switch)" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) { "peridot", MOXTET_IRQ_PERIDOT(0), 1, "MOX E (8 port switch)" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) { "usb3", MOXTET_IRQ_USB3, 2, "MOX F (USB 3.0)" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) { "pci-bridge", -1, 0, "MOX G (Mini-PCIe bridge)" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) static inline bool mox_module_known(unsigned int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) return id >= TURRIS_MOX_MODULE_FIRST && id <= TURRIS_MOX_MODULE_LAST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) static inline const char *mox_module_name(unsigned int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) if (mox_module_known(id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) return mox_module_table[id].name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) return "unknown";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define DEF_MODULE_ATTR(name, fmt, ...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static ssize_t \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) module_##name##_show(struct device *dev, struct device_attribute *a, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) char *buf) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct moxtet_device *mdev = to_moxtet_device(dev); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) return sprintf(buf, (fmt), __VA_ARGS__); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) static DEVICE_ATTR_RO(module_##name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) DEF_MODULE_ATTR(id, "0x%x\n", mdev->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) DEF_MODULE_ATTR(name, "%s\n", mox_module_name(mdev->id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) DEF_MODULE_ATTR(description, "%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) mox_module_known(mdev->id) ? mox_module_table[mdev->id].desc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) static struct attribute *moxtet_dev_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) &dev_attr_module_id.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) &dev_attr_module_name.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) &dev_attr_module_description.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static const struct attribute_group moxtet_dev_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) .attrs = moxtet_dev_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) static const struct attribute_group *moxtet_dev_groups[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) &moxtet_dev_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) static int moxtet_match(struct device *dev, struct device_driver *drv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) struct moxtet_device *mdev = to_moxtet_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) struct moxtet_driver *tdrv = to_moxtet_driver(drv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) const enum turris_mox_module_id *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if (of_driver_match_device(dev, drv))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (!tdrv->id_table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) for (t = tdrv->id_table; *t; ++t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) if (*t == mdev->id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) static struct bus_type moxtet_bus_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) .name = "moxtet",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) .dev_groups = moxtet_dev_groups,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) .match = moxtet_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) int __moxtet_register_driver(struct module *owner,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) struct moxtet_driver *mdrv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) mdrv->driver.owner = owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) mdrv->driver.bus = &moxtet_bus_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) return driver_register(&mdrv->driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) EXPORT_SYMBOL_GPL(__moxtet_register_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) static int moxtet_dev_check(struct device *dev, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct moxtet_device *mdev = to_moxtet_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) struct moxtet_device *new_dev = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) if (mdev->moxtet == new_dev->moxtet && mdev->id == new_dev->id &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) mdev->idx == new_dev->idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static void moxtet_dev_release(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) struct moxtet_device *mdev = to_moxtet_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) put_device(mdev->moxtet->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) kfree(mdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) static struct moxtet_device *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) moxtet_alloc_device(struct moxtet *moxtet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) struct moxtet_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (!get_device(moxtet->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) dev = kzalloc(sizeof(*dev), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (!dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) put_device(moxtet->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) dev->moxtet = moxtet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) dev->dev.parent = moxtet->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) dev->dev.bus = &moxtet_bus_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) dev->dev.release = moxtet_dev_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) device_initialize(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) static int moxtet_add_device(struct moxtet_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) static DEFINE_MUTEX(add_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) if (dev->idx >= TURRIS_MOX_MAX_MODULES || dev->id > 0xf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) dev_set_name(&dev->dev, "moxtet-%s.%u", mox_module_name(dev->id),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) dev->idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) mutex_lock(&add_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) ret = bus_for_each_dev(&moxtet_bus_type, NULL, dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) moxtet_dev_check);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) ret = device_add(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) dev_err(dev->moxtet->dev, "can't add %s, status %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) dev_name(dev->moxtet->dev), ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) mutex_unlock(&add_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) static int __unregister(struct device *dev, void *null)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) if (dev->of_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) of_node_clear_flag(dev->of_node, OF_POPULATED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) of_node_put(dev->of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) device_unregister(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) static struct moxtet_device *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) of_register_moxtet_device(struct moxtet *moxtet, struct device_node *nc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) struct moxtet_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) dev = moxtet_alloc_device(moxtet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (!dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) dev_err(moxtet->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) "Moxtet device alloc error for %pOF\n", nc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) ret = of_property_read_u32(nc, "reg", &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) dev_err(moxtet->dev, "%pOF has no valid 'reg' property (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) nc, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) goto err_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) dev->idx = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) if (dev->idx >= TURRIS_MOX_MAX_MODULES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) dev_err(moxtet->dev, "%pOF Moxtet address 0x%x out of range\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) nc, dev->idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) goto err_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) dev->id = moxtet->modules[dev->idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) if (!dev->id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) dev_err(moxtet->dev, "%pOF Moxtet address 0x%x is empty\n", nc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) dev->idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) goto err_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) of_node_get(nc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) dev->dev.of_node = nc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) ret = moxtet_add_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) dev_err(moxtet->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) "Moxtet device register error for %pOF\n", nc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) of_node_put(nc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) goto err_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) return dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) err_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) put_device(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) static void of_register_moxtet_devices(struct moxtet *moxtet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) struct moxtet_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) struct device_node *nc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (!moxtet->dev->of_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) for_each_available_child_of_node(moxtet->dev->of_node, nc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (of_node_test_and_set_flag(nc, OF_POPULATED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) dev = of_register_moxtet_device(moxtet, nc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) if (IS_ERR(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) dev_warn(moxtet->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) "Failed to create Moxtet device for %pOF\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) nc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) of_node_clear_flag(nc, OF_POPULATED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) moxtet_register_devices_from_topology(struct moxtet *moxtet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) struct moxtet_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) for (i = 0; i < moxtet->count; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) dev = moxtet_alloc_device(moxtet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) if (!dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) dev_err(moxtet->dev, "Moxtet device %u alloc error\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) dev->idx = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) dev->id = moxtet->modules[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) ret = moxtet_add_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) if (ret && ret != -EBUSY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) put_device(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) dev_err(moxtet->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) "Moxtet device %u register error: %i\n", i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) * @nsame: how many modules with same id are already in moxtet->modules
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) static int moxtet_set_irq(struct moxtet *moxtet, int idx, int id, int nsame)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) int i, first;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) struct moxtet_irqpos *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) first = mox_module_table[id].hwirq_base +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) nsame * mox_module_table[id].nirqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) if (first + mox_module_table[id].nirqs > MOXTET_NIRQS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) for (i = 0; i < mox_module_table[id].nirqs; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) pos = &moxtet->irq.position[first + i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) pos->idx = idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) pos->bit = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) moxtet->irq.exists |= BIT(first + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) static int moxtet_find_topology(struct moxtet *moxtet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) u8 buf[TURRIS_MOX_MAX_MODULES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) int cnts[TURRIS_MOX_MODULE_LAST];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) memset(cnts, 0, sizeof(cnts));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) ret = spi_read(to_spi_device(moxtet->dev), buf, TURRIS_MOX_MAX_MODULES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) if (buf[0] == TURRIS_MOX_CPU_ID_EMMC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) dev_info(moxtet->dev, "Found MOX A (eMMC CPU) module\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) } else if (buf[0] == TURRIS_MOX_CPU_ID_SD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) dev_info(moxtet->dev, "Found MOX A (CPU) module\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) dev_err(moxtet->dev, "Invalid Turris MOX A CPU module 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) buf[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) moxtet->count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) for (i = 1; i < TURRIS_MOX_MAX_MODULES; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if (buf[i] == 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) id = buf[i] & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) moxtet->modules[i-1] = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) ++moxtet->count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) if (mox_module_known(id)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) dev_info(moxtet->dev, "Found %s module\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) mox_module_table[id].desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (moxtet_set_irq(moxtet, i-1, id, cnts[id]++) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) dev_err(moxtet->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) " Cannot set IRQ for module %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) mox_module_table[id].desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) dev_warn(moxtet->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) "Unknown Moxtet module found (ID 0x%02x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) static int moxtet_spi_read(struct moxtet *moxtet, u8 *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) struct spi_transfer xfer = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) .rx_buf = buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) .tx_buf = moxtet->tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) .len = moxtet->count + 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) mutex_lock(&moxtet->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) ret = spi_sync_transfer(to_spi_device(moxtet->dev), &xfer, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) mutex_unlock(&moxtet->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) int moxtet_device_read(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) struct moxtet_device *mdev = to_moxtet_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) struct moxtet *moxtet = mdev->moxtet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) u8 buf[TURRIS_MOX_MAX_MODULES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) if (mdev->idx >= moxtet->count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) ret = moxtet_spi_read(moxtet, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) return buf[mdev->idx + 1] >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) EXPORT_SYMBOL_GPL(moxtet_device_read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) int moxtet_device_write(struct device *dev, u8 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) struct moxtet_device *mdev = to_moxtet_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) struct moxtet *moxtet = mdev->moxtet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) if (mdev->idx >= moxtet->count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) mutex_lock(&moxtet->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) moxtet->tx[moxtet->count - mdev->idx] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) ret = spi_write(to_spi_device(moxtet->dev), moxtet->tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) moxtet->count + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) mutex_unlock(&moxtet->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) EXPORT_SYMBOL_GPL(moxtet_device_write);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) int moxtet_device_written(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) struct moxtet_device *mdev = to_moxtet_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) struct moxtet *moxtet = mdev->moxtet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) if (mdev->idx >= moxtet->count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) return moxtet->tx[moxtet->count - mdev->idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) EXPORT_SYMBOL_GPL(moxtet_device_written);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) #ifdef CONFIG_DEBUG_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) static int moxtet_debug_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) file->private_data = inode->i_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) return nonseekable_open(inode, file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) static ssize_t input_read(struct file *file, char __user *buf, size_t len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) struct moxtet *moxtet = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) u8 bin[TURRIS_MOX_MAX_MODULES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) u8 hex[sizeof(bin) * 2 + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) int ret, n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) ret = moxtet_spi_read(moxtet, bin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) n = moxtet->count + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) bin2hex(hex, bin, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) hex[2*n] = '\n';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) return simple_read_from_buffer(buf, len, ppos, hex, 2*n + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) static const struct file_operations input_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) .open = moxtet_debug_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) .read = input_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) .llseek = no_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) static ssize_t output_read(struct file *file, char __user *buf, size_t len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) struct moxtet *moxtet = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) u8 hex[TURRIS_MOX_MAX_MODULES * 2 + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) u8 *p = hex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) mutex_lock(&moxtet->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) for (i = 0; i < moxtet->count; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) p = hex_byte_pack(p, moxtet->tx[moxtet->count - i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) mutex_unlock(&moxtet->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) *p++ = '\n';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) return simple_read_from_buffer(buf, len, ppos, hex, p - hex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) static ssize_t output_write(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) size_t len, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) struct moxtet *moxtet = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) u8 bin[TURRIS_MOX_MAX_MODULES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) u8 hex[sizeof(bin) * 2 + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) ssize_t res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) loff_t dummy = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) int err, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) if (len > 2 * moxtet->count + 1 || len < 2 * moxtet->count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) res = simple_write_to_buffer(hex, sizeof(hex), &dummy, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) if (res < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) if (len % 2 == 1 && hex[len - 1] != '\n')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) err = hex2bin(bin, hex, moxtet->count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) mutex_lock(&moxtet->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) for (i = 0; i < moxtet->count; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) moxtet->tx[moxtet->count - i] = bin[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) err = spi_write(to_spi_device(moxtet->dev), moxtet->tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) moxtet->count + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) mutex_unlock(&moxtet->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) return err < 0 ? err : len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) static const struct file_operations output_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) .open = moxtet_debug_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) .read = output_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) .write = output_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) .llseek = no_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) static int moxtet_register_debugfs(struct moxtet *moxtet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) struct dentry *root, *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) root = debugfs_create_dir("moxtet", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) if (IS_ERR(root))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) return PTR_ERR(root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) entry = debugfs_create_file_unsafe("input", 0444, root, moxtet,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) &input_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) if (IS_ERR(entry))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) goto err_remove;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) entry = debugfs_create_file_unsafe("output", 0644, root, moxtet,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) &output_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) if (IS_ERR(entry))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) goto err_remove;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) moxtet->debugfs_root = root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) err_remove:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) debugfs_remove_recursive(root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) return PTR_ERR(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) static void moxtet_unregister_debugfs(struct moxtet *moxtet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) debugfs_remove_recursive(moxtet->debugfs_root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) static inline int moxtet_register_debugfs(struct moxtet *moxtet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) static inline void moxtet_unregister_debugfs(struct moxtet *moxtet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) static int moxtet_irq_domain_map(struct irq_domain *d, unsigned int irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) irq_hw_number_t hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) struct moxtet *moxtet = d->host_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) if (hw >= MOXTET_NIRQS || !(moxtet->irq.exists & BIT(hw))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) dev_err(moxtet->dev, "Invalid hw irq number\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) irq_set_chip_data(irq, d->host_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) irq_set_chip_and_handler(irq, &moxtet->irq.chip, handle_level_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) static int moxtet_irq_domain_xlate(struct irq_domain *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) struct device_node *ctrlr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) const u32 *intspec, unsigned int intsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) unsigned long *out_hwirq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) unsigned int *out_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) struct moxtet *moxtet = d->host_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) if (WARN_ON(intsize < 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) irq = intspec[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) if (irq >= MOXTET_NIRQS || !(moxtet->irq.exists & BIT(irq)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) *out_hwirq = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) *out_type = IRQ_TYPE_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) static const struct irq_domain_ops moxtet_irq_domain = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) .map = moxtet_irq_domain_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) .xlate = moxtet_irq_domain_xlate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) static void moxtet_irq_mask(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) struct moxtet *moxtet = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) moxtet->irq.masked |= BIT(d->hwirq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) static void moxtet_irq_unmask(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) struct moxtet *moxtet = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) moxtet->irq.masked &= ~BIT(d->hwirq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) static void moxtet_irq_print_chip(struct irq_data *d, struct seq_file *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) struct moxtet *moxtet = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) struct moxtet_irqpos *pos = &moxtet->irq.position[d->hwirq];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) id = moxtet->modules[pos->idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) seq_printf(p, " moxtet-%s.%i#%i", mox_module_name(id), pos->idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) pos->bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) static const struct irq_chip moxtet_irq_chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) .name = "moxtet",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) .irq_mask = moxtet_irq_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) .irq_unmask = moxtet_irq_unmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) .irq_print_chip = moxtet_irq_print_chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) static int moxtet_irq_read(struct moxtet *moxtet, unsigned long *map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) struct moxtet_irqpos *pos = moxtet->irq.position;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) u8 buf[TURRIS_MOX_MAX_MODULES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) ret = moxtet_spi_read(moxtet, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) *map = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) for_each_set_bit(i, &moxtet->irq.exists, MOXTET_NIRQS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) if (!(buf[pos[i].idx + 1] & BIT(4 + pos[i].bit)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) set_bit(i, map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) static irqreturn_t moxtet_irq_thread_fn(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) struct moxtet *moxtet = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) unsigned long set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) int nhandled = 0, i, sub_irq, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) ret = moxtet_irq_read(moxtet, &set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) set &= ~moxtet->irq.masked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) for_each_set_bit(i, &set, MOXTET_NIRQS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) sub_irq = irq_find_mapping(moxtet->irq.domain, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) handle_nested_irq(sub_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) dev_dbg(moxtet->dev, "%i irq\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) ++nhandled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) ret = moxtet_irq_read(moxtet, &set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) set &= ~moxtet->irq.masked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) } while (set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) static void moxtet_irq_free(struct moxtet *moxtet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) int i, irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) for (i = 0; i < MOXTET_NIRQS; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) if (moxtet->irq.exists & BIT(i)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) irq = irq_find_mapping(moxtet->irq.domain, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) irq_dispose_mapping(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) irq_domain_remove(moxtet->irq.domain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) static int moxtet_irq_setup(struct moxtet *moxtet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) moxtet->irq.domain = irq_domain_add_simple(moxtet->dev->of_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) MOXTET_NIRQS, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) &moxtet_irq_domain, moxtet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) if (moxtet->irq.domain == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) dev_err(moxtet->dev, "Could not add IRQ domain\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) for (i = 0; i < MOXTET_NIRQS; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) if (moxtet->irq.exists & BIT(i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) irq_create_mapping(moxtet->irq.domain, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) moxtet->irq.chip = moxtet_irq_chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) moxtet->irq.masked = ~0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) ret = request_threaded_irq(moxtet->dev_irq, NULL, moxtet_irq_thread_fn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) IRQF_ONESHOT, "moxtet", moxtet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) goto err_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) err_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) moxtet_irq_free(moxtet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) static int moxtet_probe(struct spi_device *spi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) struct moxtet *moxtet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) ret = spi_setup(spi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) moxtet = devm_kzalloc(&spi->dev, sizeof(struct moxtet),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) if (!moxtet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) moxtet->dev = &spi->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) spi_set_drvdata(spi, moxtet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) mutex_init(&moxtet->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) moxtet->dev_irq = of_irq_get(moxtet->dev->of_node, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) if (moxtet->dev_irq == -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) return -EPROBE_DEFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) if (moxtet->dev_irq <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) dev_err(moxtet->dev, "No IRQ resource found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) ret = moxtet_find_topology(moxtet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if (moxtet->irq.exists) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) ret = moxtet_irq_setup(moxtet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) of_register_moxtet_devices(moxtet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) moxtet_register_devices_from_topology(moxtet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) ret = moxtet_register_debugfs(moxtet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) dev_warn(moxtet->dev, "Failed creating debugfs entries: %i\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) static int moxtet_remove(struct spi_device *spi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) struct moxtet *moxtet = spi_get_drvdata(spi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) free_irq(moxtet->dev_irq, moxtet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) moxtet_irq_free(moxtet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) moxtet_unregister_debugfs(moxtet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) device_for_each_child(moxtet->dev, NULL, __unregister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) mutex_destroy(&moxtet->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) static const struct of_device_id moxtet_dt_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) { .compatible = "cznic,moxtet" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) MODULE_DEVICE_TABLE(of, moxtet_dt_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) static struct spi_driver moxtet_spi_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) .name = "moxtet",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) .of_match_table = moxtet_dt_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) .probe = moxtet_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) .remove = moxtet_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) static int __init moxtet_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) ret = bus_register(&moxtet_bus_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) pr_err("moxtet bus registration failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) ret = spi_register_driver(&moxtet_spi_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) pr_err("moxtet spi driver registration failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) goto error_bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) error_bus:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) bus_unregister(&moxtet_bus_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) postcore_initcall_sync(moxtet_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) static void __exit moxtet_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) spi_unregister_driver(&moxtet_spi_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) bus_unregister(&moxtet_bus_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) module_exit(moxtet_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) MODULE_AUTHOR("Marek Behun <marek.behun@nic.cz>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) MODULE_DESCRIPTION("CZ.NIC's Turris Mox module configuration bus");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) MODULE_LICENSE("GPL v2");