Lines Matching full:stm
3 * System Trace Module (STM) infrastructure
6 * STM class implements generic infrastructure for System Trace Module devices
19 #include <linux/stm.h>
23 #include "stm.h"
25 #include <uapi/linux/stm.h>
30 * The SRCU here makes sure that STM device doesn't disappear from under a
40 struct stm_device *stm = to_stm_device(dev); in masters_show() local
43 ret = sprintf(buf, "%u %u\n", stm->data->sw_start, stm->data->sw_end); in masters_show()
54 struct stm_device *stm = to_stm_device(dev); in channels_show() local
57 ret = sprintf(buf, "%u\n", stm->data->sw_nchannels); in channels_show()
68 struct stm_device *stm = to_stm_device(dev); in hw_override_show() local
71 ret = sprintf(buf, "%u\n", stm->data->hw_override); in hw_override_show()
85 ATTRIBUTE_GROUPS(stm);
88 .name = "stm",
93 * stm_find_device() - find stm device by name
96 * This is called when either policy gets assigned to an stm device or an
97 * stm_source device gets linked to an stm device.
102 * Return: stm device pointer or null if lookup failed.
106 struct stm_device *stm; in stm_find_device() local
116 stm = to_stm_device(dev); in stm_find_device()
117 if (!try_module_get(stm->owner)) { in stm_find_device()
123 return stm; in stm_find_device()
127 * stm_put_device() - drop references on the stm device
128 * @stm: stm device, previously acquired by stm_find_device()
133 void stm_put_device(struct stm_device *stm) in stm_put_device() argument
135 module_put(stm->owner); in stm_put_device()
136 put_device(&stm->dev); in stm_put_device()
151 stm_master(struct stm_device *stm, unsigned int idx) in stm_master() argument
153 if (idx < stm->data->sw_start || idx > stm->data->sw_end) in stm_master()
156 return __stm_master(stm, idx); in stm_master()
159 static int stp_master_alloc(struct stm_device *stm, unsigned int idx) in stp_master_alloc() argument
164 BITS_TO_LONGS(stm->data->sw_nchannels)), in stp_master_alloc()
169 master->nr_free = stm->data->sw_nchannels; in stp_master_alloc()
170 __stm_master(stm, idx) = master; in stp_master_alloc()
175 static void stp_master_free(struct stm_device *stm, unsigned int idx) in stp_master_free() argument
177 struct stp_master *master = stm_master(stm, idx); in stp_master_free()
182 __stm_master(stm, idx) = NULL; in stp_master_free()
186 static void stm_output_claim(struct stm_device *stm, struct stm_output *output) in stm_output_claim() argument
188 struct stp_master *master = stm_master(stm, output->master); in stm_output_claim()
190 lockdep_assert_held(&stm->mc_lock); in stm_output_claim()
203 stm_output_disclaim(struct stm_device *stm, struct stm_output *output) in stm_output_disclaim() argument
205 struct stp_master *master = stm_master(stm, output->master); in stm_output_disclaim()
207 lockdep_assert_held(&stm->mc_lock); in stm_output_disclaim()
248 stm_find_master_chan(struct stm_device *stm, unsigned int width, in stm_find_master_chan() argument
257 if (!stm_master(stm, midx)) { in stm_find_master_chan()
258 err = stp_master_alloc(stm, midx); in stm_find_master_chan()
263 master = stm_master(stm, midx); in stm_find_master_chan()
281 static int stm_output_assign(struct stm_device *stm, unsigned int width, in stm_output_assign() argument
288 if (width > stm->data->sw_nchannels) in stm_output_assign()
301 spin_lock(&stm->mc_lock); in stm_output_assign()
307 ret = stm_find_master_chan(stm, width, &midx, mend, &cidx, cend); in stm_output_assign()
314 if (stm->pdrv->output_open) { in stm_output_assign()
321 ret = stm->pdrv->output_open(priv, output); in stm_output_assign()
326 stm_output_claim(stm, output); in stm_output_assign()
327 dev_dbg(&stm->dev, "assigned %u:%u (+%u)\n", midx, cidx, width); in stm_output_assign()
335 spin_unlock(&stm->mc_lock); in stm_output_assign()
340 static void stm_output_free(struct stm_device *stm, struct stm_output *output) in stm_output_free() argument
342 spin_lock(&stm->mc_lock); in stm_output_free()
345 stm_output_disclaim(stm, output); in stm_output_free()
346 if (stm->pdrv && stm->pdrv->output_close) in stm_output_free()
347 stm->pdrv->output_close(output); in stm_output_free()
349 spin_unlock(&stm->mc_lock); in stm_output_free()
366 * Modules can implement STM protocol drivers and (un-)register them
367 * with the STM class framework.
502 stmf->stm = to_stm_device(dev); in stm_char_open()
504 if (!try_module_get(stmf->stm->owner)) in stm_char_open()
523 struct stm_device *stm = stmf->stm; in stm_char_release() local
525 if (stm->data->unlink) in stm_char_release()
526 stm->data->unlink(stm->data, stmf->output.master, in stm_char_release()
529 stm_output_free(stm, &stmf->output); in stm_char_release()
535 stm_put_device(stm); in stm_char_release()
542 stm_assign_first_policy(struct stm_device *stm, struct stm_output *output, in stm_assign_first_policy() argument
555 pn = stp_policy_node_lookup(stm, ids[n]); in stm_assign_first_policy()
560 err = stm_output_assign(stm, width, pn, output); in stm_assign_first_policy()
569 * @data: stm driver's data
602 stm_write(struct stm_device *stm, struct stm_output *output, in stm_write() argument
607 /* stm->pdrv is serialized against policy_mutex */ in stm_write()
608 if (!stm->pdrv) in stm_write()
611 err = stm->pdrv->write(stm->data, output, chan, buf, count); in stm_write()
622 struct stm_device *stm = stmf->stm; in stm_char_write() local
639 err = stm_assign_first_policy(stmf->stm, &stmf->output, ids, 1); in stm_char_write()
658 pm_runtime_get_sync(&stm->dev); in stm_char_write()
660 count = stm_write(stm, &stmf->output, 0, kbuf, count); in stm_char_write()
662 pm_runtime_mark_last_busy(&stm->dev); in stm_char_write()
663 pm_runtime_put_autosuspend(&stm->dev); in stm_char_write()
672 struct stm_device *stm = stmf->stm; in stm_mmap_open() local
674 pm_runtime_get(&stm->dev); in stm_mmap_open()
680 struct stm_device *stm = stmf->stm; in stm_mmap_close() local
682 pm_runtime_mark_last_busy(&stm->dev); in stm_mmap_close()
683 pm_runtime_put_autosuspend(&stm->dev); in stm_mmap_close()
694 struct stm_device *stm = stmf->stm; in stm_char_mmap() local
697 if (!stm->data->mmio_addr) in stm_char_mmap()
705 if (stmf->output.nr_chans * stm->data->sw_mmiosz != size) in stm_char_mmap()
708 phys = stm->data->mmio_addr(stm->data, stmf->output.master, in stm_char_mmap()
715 pm_runtime_get_sync(&stm->dev); in stm_char_mmap()
727 struct stm_device *stm = stmf->stm; in stm_char_policy_set_ioctl() local
758 if (stm->data->sw_mmiosz) in stm_char_policy_set_ioctl()
759 wlimit = PAGE_SIZE / stm->data->sw_mmiosz; in stm_char_policy_set_ioctl()
765 ret = stm_assign_first_policy(stmf->stm, &stmf->output, ids, in stm_char_policy_set_ioctl()
770 if (stm->data->link) in stm_char_policy_set_ioctl()
771 ret = stm->data->link(stm->data, stmf->output.master, in stm_char_policy_set_ioctl()
775 stm_output_free(stmf->stm, &stmf->output); in stm_char_policy_set_ioctl()
801 struct stm_data *stm_data = stmf->stm->data; in stm_char_ioctl()
847 struct stm_device *stm = to_stm_device(dev); in stm_device_release() local
849 vfree(stm); in stm_device_release()
855 struct stm_device *stm; in stm_register_device() local
866 stm = vzalloc(sizeof(*stm) + nmasters * sizeof(void *)); in stm_register_device()
867 if (!stm) in stm_register_device()
870 stm->major = register_chrdev(0, stm_data->name, &stm_fops); in stm_register_device()
871 if (stm->major < 0) in stm_register_device()
874 device_initialize(&stm->dev); in stm_register_device()
875 stm->dev.devt = MKDEV(stm->major, 0); in stm_register_device()
876 stm->dev.class = &stm_class; in stm_register_device()
877 stm->dev.parent = parent; in stm_register_device()
878 stm->dev.release = stm_device_release; in stm_register_device()
880 mutex_init(&stm->link_mutex); in stm_register_device()
881 spin_lock_init(&stm->link_lock); in stm_register_device()
882 INIT_LIST_HEAD(&stm->link_list); in stm_register_device()
885 spin_lock_init(&stm->mc_lock); in stm_register_device()
886 mutex_init(&stm->policy_mutex); in stm_register_device()
887 stm->sw_nmasters = nmasters; in stm_register_device()
888 stm->owner = owner; in stm_register_device()
889 stm->data = stm_data; in stm_register_device()
890 stm_data->stm = stm; in stm_register_device()
892 err = kobject_set_name(&stm->dev.kobj, "%s", stm_data->name); in stm_register_device()
896 err = device_add(&stm->dev); in stm_register_device()
905 pm_runtime_no_callbacks(&stm->dev); in stm_register_device()
906 pm_runtime_use_autosuspend(&stm->dev); in stm_register_device()
907 pm_runtime_set_autosuspend_delay(&stm->dev, 2000); in stm_register_device()
908 pm_runtime_set_suspended(&stm->dev); in stm_register_device()
909 pm_runtime_enable(&stm->dev); in stm_register_device()
914 unregister_chrdev(stm->major, stm_data->name); in stm_register_device()
917 put_device(&stm->dev); in stm_register_device()
919 vfree(stm); in stm_register_device()
926 struct stm_device *stm);
930 struct stm_device *stm = stm_data->stm; in stm_unregister_device() local
934 pm_runtime_dont_use_autosuspend(&stm->dev); in stm_unregister_device()
935 pm_runtime_disable(&stm->dev); in stm_unregister_device()
937 mutex_lock(&stm->link_mutex); in stm_unregister_device()
938 list_for_each_entry_safe(src, iter, &stm->link_list, link_entry) { in stm_unregister_device()
939 ret = __stm_source_link_drop(src, stm); in stm_unregister_device()
941 * src <-> stm link must not change under the same in stm_unregister_device()
942 * stm::link_mutex, so complain loudly if it has; in stm_unregister_device()
944 * not connected to this stm and it should be otherwise in stm_unregister_device()
945 * safe to proceed with the tear-down of stm. in stm_unregister_device()
949 mutex_unlock(&stm->link_mutex); in stm_unregister_device()
953 unregister_chrdev(stm->major, stm_data->name); in stm_unregister_device()
955 mutex_lock(&stm->policy_mutex); in stm_unregister_device()
956 if (stm->policy) in stm_unregister_device()
957 stp_policy_unbind(stm->policy); in stm_unregister_device()
958 mutex_unlock(&stm->policy_mutex); in stm_unregister_device()
960 for (i = stm->data->sw_start; i <= stm->data->sw_end; i++) in stm_unregister_device()
961 stp_master_free(stm, i); in stm_unregister_device()
963 device_unregister(&stm->dev); in stm_unregister_device()
964 stm_data->stm = NULL; in stm_unregister_device()
969 * stm::link_list access serialization uses a spinlock and a mutex; holding
974 * stm::link_mutex
975 * stm::link_lock
980 * stm_source_link_add() - connect an stm_source device to an stm device
982 * @stm: stm device
984 * This function establishes a link from stm_source to an stm device so that
990 struct stm_device *stm) in stm_source_link_add() argument
995 mutex_lock(&stm->link_mutex); in stm_source_link_add()
996 spin_lock(&stm->link_lock); in stm_source_link_add()
1000 rcu_assign_pointer(src->link, stm); in stm_source_link_add()
1001 list_add_tail(&src->link_entry, &stm->link_list); in stm_source_link_add()
1004 spin_unlock(&stm->link_lock); in stm_source_link_add()
1005 mutex_unlock(&stm->link_mutex); in stm_source_link_add()
1011 err = stm_assign_first_policy(stm, &src->output, ids, in stm_source_link_add()
1018 /* this is to notify the STM device that a new link has been made */ in stm_source_link_add()
1019 if (stm->data->link) in stm_source_link_add()
1020 err = stm->data->link(stm->data, src->output.master, in stm_source_link_add()
1033 stm_output_free(stm, &src->output); in stm_source_link_add()
1036 mutex_lock(&stm->link_mutex); in stm_source_link_add()
1037 spin_lock(&stm->link_lock); in stm_source_link_add()
1044 spin_unlock(&stm->link_lock); in stm_source_link_add()
1045 mutex_unlock(&stm->link_mutex); in stm_source_link_add()
1051 * __stm_source_link_drop() - detach stm_source from an stm device
1053 * @stm: stm device
1055 * If @stm is @src::link, disconnect them from one another and put the
1056 * reference on the @stm device.
1058 * Caller must hold stm::link_mutex.
1061 struct stm_device *stm) in __stm_source_link_drop() argument
1066 lockdep_assert_held(&stm->link_mutex); in __stm_source_link_drop()
1068 /* for stm::link_list modification, we hold both mutex and spinlock */ in __stm_source_link_drop()
1069 spin_lock(&stm->link_lock); in __stm_source_link_drop()
1078 if (link != stm) { in __stm_source_link_drop()
1093 spin_unlock(&stm->link_lock); in __stm_source_link_drop()
1096 * Call the unlink callbacks for both source and stm, when we know in __stm_source_link_drop()
1103 if (stm->data->unlink) in __stm_source_link_drop()
1104 stm->data->unlink(stm->data, src->output.master, in __stm_source_link_drop()
1112 * stm_source_link_drop() - detach stm_source from its stm device
1115 * Unlinking means disconnecting from source's STM device; after this
1116 * writes will be unsuccessful until it is linked to a new STM device.
1119 * the existing link (if any), or on linked STM device's de-registration.
1123 struct stm_device *stm; in stm_source_link_drop() local
1129 * The stm device will be valid for the duration of this in stm_source_link_drop()
1133 stm = srcu_dereference(src->link, &stm_source_srcu); in stm_source_link_drop()
1136 if (stm) { in stm_source_link_drop()
1137 mutex_lock(&stm->link_mutex); in stm_source_link_drop()
1138 ret = __stm_source_link_drop(src, stm); in stm_source_link_drop()
1139 mutex_unlock(&stm->link_mutex); in stm_source_link_drop()
1154 struct stm_device *stm; in stm_source_link_show() local
1158 stm = srcu_dereference(src->link, &stm_source_srcu); in stm_source_link_show()
1160 stm ? dev_name(&stm->dev) : "<none>"); in stm_source_link_show()
1219 * data to an stm device once linked.
1288 struct stm_device *stm; in stm_source_write() local
1299 stm = srcu_dereference(src->link, &stm_source_srcu); in stm_source_write()
1300 if (stm) in stm_source_write()
1301 count = stm_write(stm, &src->output, chan, buf, count); in stm_source_write()