12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324 |
- From 529419e047ed78101c90bfe75b9aef900c71a47e Mon Sep 17 00:00:00 2001
- From: Maximilian Luz <luzmaximilian@gmail.com>
- Date: Sun, 23 May 2021 14:09:42 +0200
- Subject: [PATCH] platform/surface: aggregator_registry: Consolidate node
- groups for 5th- and 6th-gen devices
- 5th- and 6th-generation Surface devices have all SAM clients defined in
- ACPI, except for the platform profile/performance mode which his handled
- via the WSID (Windows Surface Integration Device). Thus, the node groups
- for those devices are the same and we can just use a single one instead
- of re-defining the same one over and over again.
- Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
- Patchset: surface-sam
- ---
- .../surface/surface_aggregator_registry.c | 47 +++++--------------
- 1 file changed, 12 insertions(+), 35 deletions(-)
- diff --git a/drivers/platform/surface/surface_aggregator_registry.c b/drivers/platform/surface/surface_aggregator_registry.c
- index ef83461fa536..4428c4330229 100644
- --- a/drivers/platform/surface/surface_aggregator_registry.c
- +++ b/drivers/platform/surface/surface_aggregator_registry.c
- @@ -119,8 +119,13 @@ static const struct software_node ssam_node_hid_base_iid6 = {
- .parent = &ssam_node_hub_base,
- };
-
- -/* Devices for Surface Book 2. */
- -static const struct software_node *ssam_node_group_sb2[] = {
- +/*
- + * Devices for 5th- and 6th-generations models:
- + * - Surface Book 2,
- + * - Surface Laptop 1 and 2,
- + * - Surface Pro 5 and 6.
- + */
- +static const struct software_node *ssam_node_group_gen5[] = {
- &ssam_node_root,
- &ssam_node_tmp_pprof,
- NULL,
- @@ -142,20 +147,6 @@ static const struct software_node *ssam_node_group_sb3[] = {
- NULL,
- };
-
- -/* Devices for Surface Laptop 1. */
- -static const struct software_node *ssam_node_group_sl1[] = {
- - &ssam_node_root,
- - &ssam_node_tmp_pprof,
- - NULL,
- -};
- -
- -/* Devices for Surface Laptop 2. */
- -static const struct software_node *ssam_node_group_sl2[] = {
- - &ssam_node_root,
- - &ssam_node_tmp_pprof,
- - NULL,
- -};
- -
- /* Devices for Surface Laptop 3 and 4. */
- static const struct software_node *ssam_node_group_sl3[] = {
- &ssam_node_root,
- @@ -177,20 +168,6 @@ static const struct software_node *ssam_node_group_slg1[] = {
- NULL,
- };
-
- -/* Devices for Surface Pro 5. */
- -static const struct software_node *ssam_node_group_sp5[] = {
- - &ssam_node_root,
- - &ssam_node_tmp_pprof,
- - NULL,
- -};
- -
- -/* Devices for Surface Pro 6. */
- -static const struct software_node *ssam_node_group_sp6[] = {
- - &ssam_node_root,
- - &ssam_node_tmp_pprof,
- - NULL,
- -};
- -
- /* Devices for Surface Pro 7 and Surface Pro 7+. */
- static const struct software_node *ssam_node_group_sp7[] = {
- &ssam_node_root,
- @@ -495,10 +472,10 @@ static struct ssam_device_driver ssam_base_hub_driver = {
-
- static const struct acpi_device_id ssam_platform_hub_match[] = {
- /* Surface Pro 4, 5, and 6 (OMBR < 0x10) */
- - { "MSHW0081", (unsigned long)ssam_node_group_sp5 },
- + { "MSHW0081", (unsigned long)ssam_node_group_gen5 },
-
- /* Surface Pro 6 (OMBR >= 0x10) */
- - { "MSHW0111", (unsigned long)ssam_node_group_sp6 },
- + { "MSHW0111", (unsigned long)ssam_node_group_gen5 },
-
- /* Surface Pro 7 */
- { "MSHW0116", (unsigned long)ssam_node_group_sp7 },
- @@ -507,16 +484,16 @@ static const struct acpi_device_id ssam_platform_hub_match[] = {
- { "MSHW0119", (unsigned long)ssam_node_group_sp7 },
-
- /* Surface Book 2 */
- - { "MSHW0107", (unsigned long)ssam_node_group_sb2 },
- + { "MSHW0107", (unsigned long)ssam_node_group_gen5 },
-
- /* Surface Book 3 */
- { "MSHW0117", (unsigned long)ssam_node_group_sb3 },
-
- /* Surface Laptop 1 */
- - { "MSHW0086", (unsigned long)ssam_node_group_sl1 },
- + { "MSHW0086", (unsigned long)ssam_node_group_gen5 },
-
- /* Surface Laptop 2 */
- - { "MSHW0112", (unsigned long)ssam_node_group_sl2 },
- + { "MSHW0112", (unsigned long)ssam_node_group_gen5 },
-
- /* Surface Laptop 3 (13", Intel) */
- { "MSHW0114", (unsigned long)ssam_node_group_sl3 },
- --
- 2.32.0
- From 7cfa1fee5d33055aac80df5c5fd98d923cf48bb6 Mon Sep 17 00:00:00 2001
- From: Maximilian Luz <luzmaximilian@gmail.com>
- Date: Fri, 4 Jun 2021 15:47:49 +0200
- Subject: [PATCH] platform/surface: aggregator: Allow registering notifiers
- without enabling events
- Currently, each SSAM event notifier is directly tied to one group of
- events. This makes sense as registering a notifier will automatically
- take care of enabling the corresponding event group and normally drivers
- only need notifications for a very limited number of events, associated
- with different callbacks for each group.
- However, there are rare cases, especially for debugging, when we want to
- get notifications for a whole event target category instead of just a
- single group of events in that category. Registering multiple notifiers,
- i.e. one per group, may be infeasible due to two issues: a) we might not
- know every event enable/disable specification as some events are
- auto-enabled by the EC and b) forwarding this to the same callback will
- lead to duplicate events as we might not know the full event
- specification to perform the appropriate filtering.
- This commit introduces observer-notifiers, which are notifiers that are
- not tied to a specific event group and do not attempt to manage any
- events. In other words, they can be registered without enabling any
- event group or incrementing the corresponding reference count and just
- act as silent observers, listening to all currently/previously enabled
- events based on their match-specification.
- Essentially, this allows us to register one single notifier for a full
- event target category, meaning that we can process all events of that
- target category in a single callback without duplication. Specifically,
- this will be used in the cdev debug interface to forward events to
- user-space via a device file from which the events can be read.
- Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
- Reviewed-by: Hans de Goede <hdegoede@redhat.com>
- Link: https://lore.kernel.org/r/20210604134755.535590-2-luzmaximilian@gmail.com
- Signed-off-by: Hans de Goede <hdegoede@redhat.com>
- Patchset: surface-sam
- ---
- .../platform/surface/aggregator/controller.c | 69 +++++++++++--------
- include/linux/surface_aggregator/controller.h | 17 +++++
- 2 files changed, 58 insertions(+), 28 deletions(-)
- diff --git a/drivers/platform/surface/aggregator/controller.c b/drivers/platform/surface/aggregator/controller.c
- index a06964aa96e7..cd3a6b77f48d 100644
- --- a/drivers/platform/surface/aggregator/controller.c
- +++ b/drivers/platform/surface/aggregator/controller.c
- @@ -2127,9 +2127,15 @@ int ssam_ctrl_notif_d0_entry(struct ssam_controller *ctrl)
- * @ctrl: The controller to register the notifier on.
- * @n: The event notifier to register.
- *
- - * Register an event notifier and increment the usage counter of the
- - * associated SAM event. If the event was previously not enabled, it will be
- - * enabled during this call.
- + * Register an event notifier. Increment the usage counter of the associated
- + * SAM event if the notifier is not marked as an observer. If the event is not
- + * marked as an observer and is currently not enabled, it will be enabled
- + * during this call. If the notifier is marked as an observer, no attempt will
- + * be made at enabling any event and no reference count will be modified.
- + *
- + * Notifiers marked as observers do not need to be associated with one specific
- + * event, i.e. as long as no event matching is performed, only the event target
- + * category needs to be set.
- *
- * Return: Returns zero on success, %-ENOSPC if there have already been
- * %INT_MAX notifiers for the event ID/type associated with the notifier block
- @@ -2138,11 +2144,10 @@ int ssam_ctrl_notif_d0_entry(struct ssam_controller *ctrl)
- * for the specific associated event, returns the status of the event-enable
- * EC-command.
- */
- -int ssam_notifier_register(struct ssam_controller *ctrl,
- - struct ssam_event_notifier *n)
- +int ssam_notifier_register(struct ssam_controller *ctrl, struct ssam_event_notifier *n)
- {
- u16 rqid = ssh_tc_to_rqid(n->event.id.target_category);
- - struct ssam_nf_refcount_entry *entry;
- + struct ssam_nf_refcount_entry *entry = NULL;
- struct ssam_nf_head *nf_head;
- struct ssam_nf *nf;
- int status;
- @@ -2155,29 +2160,32 @@ int ssam_notifier_register(struct ssam_controller *ctrl,
-
- mutex_lock(&nf->lock);
-
- - entry = ssam_nf_refcount_inc(nf, n->event.reg, n->event.id);
- - if (IS_ERR(entry)) {
- - mutex_unlock(&nf->lock);
- - return PTR_ERR(entry);
- - }
- + if (!(n->flags & SSAM_EVENT_NOTIFIER_OBSERVER)) {
- + entry = ssam_nf_refcount_inc(nf, n->event.reg, n->event.id);
- + if (IS_ERR(entry)) {
- + mutex_unlock(&nf->lock);
- + return PTR_ERR(entry);
- + }
-
- - ssam_dbg(ctrl, "enabling event (reg: %#04x, tc: %#04x, iid: %#04x, rc: %d)\n",
- - n->event.reg.target_category, n->event.id.target_category,
- - n->event.id.instance, entry->refcount);
- + ssam_dbg(ctrl, "enabling event (reg: %#04x, tc: %#04x, iid: %#04x, rc: %d)\n",
- + n->event.reg.target_category, n->event.id.target_category,
- + n->event.id.instance, entry->refcount);
- + }
-
- status = ssam_nfblk_insert(nf_head, &n->base);
- if (status) {
- - entry = ssam_nf_refcount_dec(nf, n->event.reg, n->event.id);
- - if (entry->refcount == 0)
- - kfree(entry);
- + if (entry) {
- + entry = ssam_nf_refcount_dec(nf, n->event.reg, n->event.id);
- + if (entry->refcount == 0)
- + kfree(entry);
- + }
-
- mutex_unlock(&nf->lock);
- return status;
- }
-
- - if (entry->refcount == 1) {
- - status = ssam_ssh_event_enable(ctrl, n->event.reg, n->event.id,
- - n->event.flags);
- + if (entry && entry->refcount == 1) {
- + status = ssam_ssh_event_enable(ctrl, n->event.reg, n->event.id, n->event.flags);
- if (status) {
- ssam_nfblk_remove(&n->base);
- kfree(ssam_nf_refcount_dec(nf, n->event.reg, n->event.id));
- @@ -2188,7 +2196,7 @@ int ssam_notifier_register(struct ssam_controller *ctrl,
-
- entry->flags = n->event.flags;
-
- - } else if (entry->flags != n->event.flags) {
- + } else if (entry && entry->flags != n->event.flags) {
- ssam_warn(ctrl,
- "inconsistent flags when enabling event: got %#04x, expected %#04x (reg: %#04x, tc: %#04x, iid: %#04x)\n",
- n->event.flags, entry->flags, n->event.reg.target_category,
- @@ -2205,17 +2213,16 @@ EXPORT_SYMBOL_GPL(ssam_notifier_register);
- * @ctrl: The controller the notifier has been registered on.
- * @n: The event notifier to unregister.
- *
- - * Unregister an event notifier and decrement the usage counter of the
- - * associated SAM event. If the usage counter reaches zero, the event will be
- - * disabled.
- + * Unregister an event notifier. Decrement the usage counter of the associated
- + * SAM event if the notifier is not marked as an observer. If the usage counter
- + * reaches zero, the event will be disabled.
- *
- * Return: Returns zero on success, %-ENOENT if the given notifier block has
- * not been registered on the controller. If the given notifier block was the
- * last one associated with its specific event, returns the status of the
- * event-disable EC-command.
- */
- -int ssam_notifier_unregister(struct ssam_controller *ctrl,
- - struct ssam_event_notifier *n)
- +int ssam_notifier_unregister(struct ssam_controller *ctrl, struct ssam_event_notifier *n)
- {
- u16 rqid = ssh_tc_to_rqid(n->event.id.target_category);
- struct ssam_nf_refcount_entry *entry;
- @@ -2236,6 +2243,13 @@ int ssam_notifier_unregister(struct ssam_controller *ctrl,
- return -ENOENT;
- }
-
- + /*
- + * If this is an observer notifier, do not attempt to disable the
- + * event, just remove it.
- + */
- + if (n->flags & SSAM_EVENT_NOTIFIER_OBSERVER)
- + goto remove;
- +
- entry = ssam_nf_refcount_dec(nf, n->event.reg, n->event.id);
- if (WARN_ON(!entry)) {
- /*
- @@ -2260,8 +2274,7 @@ int ssam_notifier_unregister(struct ssam_controller *ctrl,
- }
-
- if (entry->refcount == 0) {
- - status = ssam_ssh_event_disable(ctrl, n->event.reg, n->event.id,
- - n->event.flags);
- + status = ssam_ssh_event_disable(ctrl, n->event.reg, n->event.id, n->event.flags);
- kfree(entry);
- }
-
- diff --git a/include/linux/surface_aggregator/controller.h b/include/linux/surface_aggregator/controller.h
- index 0806796eabcb..cf4bb48a850e 100644
- --- a/include/linux/surface_aggregator/controller.h
- +++ b/include/linux/surface_aggregator/controller.h
- @@ -795,6 +795,20 @@ enum ssam_event_mask {
- #define SSAM_EVENT_REGISTRY_REG \
- SSAM_EVENT_REGISTRY(SSAM_SSH_TC_REG, 0x02, 0x01, 0x02)
-
- +/**
- + * enum ssam_event_notifier_flags - Flags for event notifiers.
- + * @SSAM_EVENT_NOTIFIER_OBSERVER:
- + * The corresponding notifier acts as observer. Registering a notifier
- + * with this flag set will not attempt to enable any event. Equally,
- + * unregistering will not attempt to disable any event. Note that a
- + * notifier with this flag may not even correspond to a certain event at
- + * all, only to a specific event target category. Event matching will not
- + * be influenced by this flag.
- + */
- +enum ssam_event_notifier_flags {
- + SSAM_EVENT_NOTIFIER_OBSERVER = BIT(0),
- +};
- +
- /**
- * struct ssam_event_notifier - Notifier block for SSAM events.
- * @base: The base notifier block with callback function and priority.
- @@ -803,6 +817,7 @@ enum ssam_event_mask {
- * @event.id: ID specifying the event.
- * @event.mask: Flags determining how events are matched to the notifier.
- * @event.flags: Flags used for enabling the event.
- + * @flags: Notifier flags (see &enum ssam_event_notifier_flags).
- */
- struct ssam_event_notifier {
- struct ssam_notifier_block base;
- @@ -813,6 +828,8 @@ struct ssam_event_notifier {
- enum ssam_event_mask mask;
- u8 flags;
- } event;
- +
- + unsigned long flags;
- };
-
- int ssam_notifier_register(struct ssam_controller *ctrl,
- --
- 2.32.0
- From ae51e1e0f612e8ce069a583e189dacdfbe7616a1 Mon Sep 17 00:00:00 2001
- From: Maximilian Luz <luzmaximilian@gmail.com>
- Date: Fri, 4 Jun 2021 15:47:50 +0200
- Subject: [PATCH] platform/surface: aggregator: Allow enabling of events
- without notifiers
- We can already enable and disable SAM events via one of two ways: either
- via a (non-observer) notifier tied to a specific event group, or a
- generic event enable/disable request. In some instances, however,
- neither method may be desirable.
- The first method will tie the event enable request to a specific
- notifier, however, when we want to receive notifications for multiple
- event groups of the same target category and forward this to the same
- notifier callback, we may receive duplicate events, i.e. one event per
- registered notifier. The second method will bypass the internal
- reference counting mechanism, meaning that a disable request will
- disable the event regardless of any other client driver using it, which
- may break the functionality of that driver.
- To address this problem, add new functions that allow enabling and
- disabling of events via the event reference counting mechanism built
- into the controller, without needing to register a notifier.
- This can then be used in combination with observer notifiers to process
- multiple events of the same target category without duplication in the
- same callback function.
- Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
- Link: https://lore.kernel.org/r/20210604134755.535590-3-luzmaximilian@gmail.com
- Reviewed-by: Hans de Goede <hdegoede@redhat.com>
- Signed-off-by: Hans de Goede <hdegoede@redhat.com>
- Patchset: surface-sam
- ---
- .../platform/surface/aggregator/controller.c | 293 +++++++++++++++---
- include/linux/surface_aggregator/controller.h | 8 +
- 2 files changed, 253 insertions(+), 48 deletions(-)
- diff --git a/drivers/platform/surface/aggregator/controller.c b/drivers/platform/surface/aggregator/controller.c
- index cd3a6b77f48d..cedd0f779f7a 100644
- --- a/drivers/platform/surface/aggregator/controller.c
- +++ b/drivers/platform/surface/aggregator/controller.c
- @@ -407,6 +407,31 @@ ssam_nf_refcount_dec(struct ssam_nf *nf, struct ssam_event_registry reg,
- return NULL;
- }
-
- +/**
- + * ssam_nf_refcount_dec_free() - Decrement reference-/activation-count of the
- + * given event and free its entry if the reference count reaches zero.
- + * @nf: The notifier system reference.
- + * @reg: The registry used to enable/disable the event.
- + * @id: The event ID.
- + *
- + * Decrements the reference-/activation-count of the specified event, freeing
- + * its entry if it reaches zero.
- + *
- + * Note: ``nf->lock`` must be held when calling this function.
- + */
- +static void ssam_nf_refcount_dec_free(struct ssam_nf *nf,
- + struct ssam_event_registry reg,
- + struct ssam_event_id id)
- +{
- + struct ssam_nf_refcount_entry *entry;
- +
- + lockdep_assert_held(&nf->lock);
- +
- + entry = ssam_nf_refcount_dec(nf, reg, id);
- + if (entry && entry->refcount == 0)
- + kfree(entry);
- +}
- +
- /**
- * ssam_nf_refcount_empty() - Test if the notification system has any
- * enabled/active events.
- @@ -2122,6 +2147,109 @@ int ssam_ctrl_notif_d0_entry(struct ssam_controller *ctrl)
-
- /* -- Top-level event registry interface. ----------------------------------- */
-
- +/**
- + * ssam_nf_refcount_enable() - Enable event for reference count entry if it has
- + * not already been enabled.
- + * @ctrl: The controller to enable the event on.
- + * @entry: The reference count entry for the event to be enabled.
- + * @flags: The flags used for enabling the event on the EC.
- + *
- + * Enable the event associated with the given reference count entry if the
- + * reference count equals one, i.e. the event has not previously been enabled.
- + * If the event has already been enabled (i.e. reference count not equal to
- + * one), check that the flags used for enabling match and warn about this if
- + * they do not.
- + *
- + * This does not modify the reference count itself, which is done with
- + * ssam_nf_refcount_inc() / ssam_nf_refcount_dec().
- + *
- + * Note: ``nf->lock`` must be held when calling this function.
- + *
- + * Return: Returns zero on success. If the event is enabled by this call,
- + * returns the status of the event-enable EC command.
- + */
- +static int ssam_nf_refcount_enable(struct ssam_controller *ctrl,
- + struct ssam_nf_refcount_entry *entry, u8 flags)
- +{
- + const struct ssam_event_registry reg = entry->key.reg;
- + const struct ssam_event_id id = entry->key.id;
- + struct ssam_nf *nf = &ctrl->cplt.event.notif;
- + int status;
- +
- + lockdep_assert_held(&nf->lock);
- +
- + ssam_dbg(ctrl, "enabling event (reg: %#04x, tc: %#04x, iid: %#04x, rc: %d)\n",
- + reg.target_category, id.target_category, id.instance, entry->refcount);
- +
- + if (entry->refcount == 1) {
- + status = ssam_ssh_event_enable(ctrl, reg, id, flags);
- + if (status)
- + return status;
- +
- + entry->flags = flags;
- +
- + } else if (entry->flags != flags) {
- + ssam_warn(ctrl,
- + "inconsistent flags when enabling event: got %#04x, expected %#04x (reg: %#04x, tc: %#04x, iid: %#04x)\n",
- + flags, entry->flags, reg.target_category, id.target_category,
- + id.instance);
- + }
- +
- + return 0;
- +}
- +
- +/**
- + * ssam_nf_refcount_disable_free() - Disable event for reference count entry if it is
- + * no longer in use and free the corresponding entry.
- + * @ctrl: The controller to disable the event on.
- + * @entry: The reference count entry for the event to be disabled.
- + * @flags: The flags used for enabling the event on the EC.
- + *
- + * If the reference count equals zero, i.e. the event is no longer requested by
- + * any client, the event will be disabled and the corresponding reference count
- + * entry freed. The reference count entry must not be used any more after a
- + * call to this function.
- + *
- + * Also checks if the flags used for disabling the event match the flags used
- + * for enabling the event and warns if they do not (regardless of reference
- + * count).
- + *
- + * This does not modify the reference count itself, which is done with
- + * ssam_nf_refcount_inc() / ssam_nf_refcount_dec().
- + *
- + * Note: ``nf->lock`` must be held when calling this function.
- + *
- + * Return: Returns zero on success. If the event is disabled by this call,
- + * returns the status of the event-enable EC command.
- + */
- +static int ssam_nf_refcount_disable_free(struct ssam_controller *ctrl,
- + struct ssam_nf_refcount_entry *entry, u8 flags)
- +{
- + const struct ssam_event_registry reg = entry->key.reg;
- + const struct ssam_event_id id = entry->key.id;
- + struct ssam_nf *nf = &ctrl->cplt.event.notif;
- + int status;
- +
- + lockdep_assert_held(&nf->lock);
- +
- + ssam_dbg(ctrl, "disabling event (reg: %#04x, tc: %#04x, iid: %#04x, rc: %d)\n",
- + reg.target_category, id.target_category, id.instance, entry->refcount);
- +
- + if (entry->flags != flags) {
- + ssam_warn(ctrl,
- + "inconsistent flags when disabling event: got %#04x, expected %#04x (reg: %#04x, tc: %#04x, iid: %#04x)\n",
- + flags, entry->flags, reg.target_category, id.target_category,
- + id.instance);
- + }
- +
- + if (entry->refcount == 0) {
- + status = ssam_ssh_event_disable(ctrl, reg, id, flags);
- + kfree(entry);
- + }
- +
- + return status;
- +}
- +
- /**
- * ssam_notifier_register() - Register an event notifier.
- * @ctrl: The controller to register the notifier on.
- @@ -2166,41 +2294,26 @@ int ssam_notifier_register(struct ssam_controller *ctrl, struct ssam_event_notif
- mutex_unlock(&nf->lock);
- return PTR_ERR(entry);
- }
- -
- - ssam_dbg(ctrl, "enabling event (reg: %#04x, tc: %#04x, iid: %#04x, rc: %d)\n",
- - n->event.reg.target_category, n->event.id.target_category,
- - n->event.id.instance, entry->refcount);
- }
-
- status = ssam_nfblk_insert(nf_head, &n->base);
- if (status) {
- - if (entry) {
- - entry = ssam_nf_refcount_dec(nf, n->event.reg, n->event.id);
- - if (entry->refcount == 0)
- - kfree(entry);
- - }
- + if (entry)
- + ssam_nf_refcount_dec_free(nf, n->event.reg, n->event.id);
-
- mutex_unlock(&nf->lock);
- return status;
- }
-
- - if (entry && entry->refcount == 1) {
- - status = ssam_ssh_event_enable(ctrl, n->event.reg, n->event.id, n->event.flags);
- + if (entry) {
- + status = ssam_nf_refcount_enable(ctrl, entry, n->event.flags);
- if (status) {
- ssam_nfblk_remove(&n->base);
- - kfree(ssam_nf_refcount_dec(nf, n->event.reg, n->event.id));
- + ssam_nf_refcount_dec_free(nf, n->event.reg, n->event.id);
- mutex_unlock(&nf->lock);
- synchronize_srcu(&nf_head->srcu);
- return status;
- }
- -
- - entry->flags = n->event.flags;
- -
- - } else if (entry && entry->flags != n->event.flags) {
- - ssam_warn(ctrl,
- - "inconsistent flags when enabling event: got %#04x, expected %#04x (reg: %#04x, tc: %#04x, iid: %#04x)\n",
- - n->event.flags, entry->flags, n->event.reg.target_category,
- - n->event.id.target_category, n->event.id.instance);
- }
-
- mutex_unlock(&nf->lock);
- @@ -2247,35 +2360,20 @@ int ssam_notifier_unregister(struct ssam_controller *ctrl, struct ssam_event_not
- * If this is an observer notifier, do not attempt to disable the
- * event, just remove it.
- */
- - if (n->flags & SSAM_EVENT_NOTIFIER_OBSERVER)
- - goto remove;
- -
- - entry = ssam_nf_refcount_dec(nf, n->event.reg, n->event.id);
- - if (WARN_ON(!entry)) {
- - /*
- - * If this does not return an entry, there's a logic error
- - * somewhere: The notifier block is registered, but the event
- - * refcount entry is not there. Remove the notifier block
- - * anyways.
- - */
- - status = -ENOENT;
- - goto remove;
- - }
- -
- - ssam_dbg(ctrl, "disabling event (reg: %#04x, tc: %#04x, iid: %#04x, rc: %d)\n",
- - n->event.reg.target_category, n->event.id.target_category,
- - n->event.id.instance, entry->refcount);
- -
- - if (entry->flags != n->event.flags) {
- - ssam_warn(ctrl,
- - "inconsistent flags when disabling event: got %#04x, expected %#04x (reg: %#04x, tc: %#04x, iid: %#04x)\n",
- - n->event.flags, entry->flags, n->event.reg.target_category,
- - n->event.id.target_category, n->event.id.instance);
- - }
- + if (!(n->flags & SSAM_EVENT_NOTIFIER_OBSERVER)) {
- + entry = ssam_nf_refcount_dec(nf, n->event.reg, n->event.id);
- + if (WARN_ON(!entry)) {
- + /*
- + * If this does not return an entry, there's a logic
- + * error somewhere: The notifier block is registered,
- + * but the event refcount entry is not there. Remove
- + * the notifier block anyways.
- + */
- + status = -ENOENT;
- + goto remove;
- + }
-
- - if (entry->refcount == 0) {
- - status = ssam_ssh_event_disable(ctrl, n->event.reg, n->event.id, n->event.flags);
- - kfree(entry);
- + status = ssam_nf_refcount_disable_free(ctrl, entry, n->event.flags);
- }
-
- remove:
- @@ -2287,6 +2385,105 @@ int ssam_notifier_unregister(struct ssam_controller *ctrl, struct ssam_event_not
- }
- EXPORT_SYMBOL_GPL(ssam_notifier_unregister);
-
- +/**
- + * ssam_controller_event_enable() - Enable the specified event.
- + * @ctrl: The controller to enable the event for.
- + * @reg: The event registry to use for enabling the event.
- + * @id: The event ID specifying the event to be enabled.
- + * @flags: The SAM event flags used for enabling the event.
- + *
- + * Increment the event reference count of the specified event. If the event has
- + * not been enabled previously, it will be enabled by this call.
- + *
- + * Note: In general, ssam_notifier_register() with a non-observer notifier
- + * should be preferred for enabling/disabling events, as this will guarantee
- + * proper ordering and event forwarding in case of errors during event
- + * enabling/disabling.
- + *
- + * Return: Returns zero on success, %-ENOSPC if the reference count for the
- + * specified event has reached its maximum, %-ENOMEM if the corresponding event
- + * entry could not be allocated. If this is the first time that this event has
- + * been enabled (i.e. the reference count was incremented from zero to one by
- + * this call), returns the status of the event-enable EC-command.
- + */
- +int ssam_controller_event_enable(struct ssam_controller *ctrl,
- + struct ssam_event_registry reg,
- + struct ssam_event_id id, u8 flags)
- +{
- + u16 rqid = ssh_tc_to_rqid(id.target_category);
- + struct ssam_nf *nf = &ctrl->cplt.event.notif;
- + struct ssam_nf_refcount_entry *entry;
- + int status;
- +
- + if (!ssh_rqid_is_event(rqid))
- + return -EINVAL;
- +
- + mutex_lock(&nf->lock);
- +
- + entry = ssam_nf_refcount_inc(nf, reg, id);
- + if (IS_ERR(entry)) {
- + mutex_unlock(&nf->lock);
- + return PTR_ERR(entry);
- + }
- +
- + status = ssam_nf_refcount_enable(ctrl, entry, flags);
- + if (status) {
- + ssam_nf_refcount_dec_free(nf, reg, id);
- + mutex_unlock(&nf->lock);
- + return status;
- + }
- +
- + mutex_unlock(&nf->lock);
- + return 0;
- +}
- +EXPORT_SYMBOL_GPL(ssam_controller_event_enable);
- +
- +/**
- + * ssam_controller_event_disable() - Disable the specified event.
- + * @ctrl: The controller to disable the event for.
- + * @reg: The event registry to use for disabling the event.
- + * @id: The event ID specifying the event to be disabled.
- + * @flags: The flags used when enabling the event.
- + *
- + * Decrement the reference count of the specified event. If the reference count
- + * reaches zero, the event will be disabled.
- + *
- + * Note: In general, ssam_notifier_register()/ssam_notifier_unregister() with a
- + * non-observer notifier should be preferred for enabling/disabling events, as
- + * this will guarantee proper ordering and event forwarding in case of errors
- + * during event enabling/disabling.
- + *
- + * Return: Returns zero on success, %-ENOENT if the given event has not been
- + * enabled on the controller. If the reference count of the event reaches zero
- + * during this call, returns the status of the event-disable EC-command.
- + */
- +int ssam_controller_event_disable(struct ssam_controller *ctrl,
- + struct ssam_event_registry reg,
- + struct ssam_event_id id, u8 flags)
- +{
- + u16 rqid = ssh_tc_to_rqid(id.target_category);
- + struct ssam_nf *nf = &ctrl->cplt.event.notif;
- + struct ssam_nf_refcount_entry *entry;
- + int status = 0;
- +
- + if (!ssh_rqid_is_event(rqid))
- + return -EINVAL;
- +
- + mutex_lock(&nf->lock);
- +
- + entry = ssam_nf_refcount_dec(nf, reg, id);
- + if (!entry) {
- + mutex_unlock(&nf->lock);
- + return -ENOENT;
- + }
- +
- + status = ssam_nf_refcount_disable_free(ctrl, entry, flags);
- +
- + mutex_unlock(&nf->lock);
- + return status;
- +}
- +EXPORT_SYMBOL_GPL(ssam_controller_event_disable);
- +
- /**
- * ssam_notifier_disable_registered() - Disable events for all registered
- * notifiers.
- diff --git a/include/linux/surface_aggregator/controller.h b/include/linux/surface_aggregator/controller.h
- index cf4bb48a850e..7965bdc669c5 100644
- --- a/include/linux/surface_aggregator/controller.h
- +++ b/include/linux/surface_aggregator/controller.h
- @@ -838,4 +838,12 @@ int ssam_notifier_register(struct ssam_controller *ctrl,
- int ssam_notifier_unregister(struct ssam_controller *ctrl,
- struct ssam_event_notifier *n);
-
- +int ssam_controller_event_enable(struct ssam_controller *ctrl,
- + struct ssam_event_registry reg,
- + struct ssam_event_id id, u8 flags);
- +
- +int ssam_controller_event_disable(struct ssam_controller *ctrl,
- + struct ssam_event_registry reg,
- + struct ssam_event_id id, u8 flags);
- +
- #endif /* _LINUX_SURFACE_AGGREGATOR_CONTROLLER_H */
- --
- 2.32.0
- From aee14cd170550e9c16fc106846056eb4d006b044 Mon Sep 17 00:00:00 2001
- From: Maximilian Luz <luzmaximilian@gmail.com>
- Date: Fri, 4 Jun 2021 15:47:51 +0200
- Subject: [PATCH] platform/surface: aggregator: Update copyright
- It's 2021, update the copyright accordingly.
- Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
- Reviewed-by: Hans de Goede <hdegoede@redhat.com>
- Link: https://lore.kernel.org/r/20210604134755.535590-4-luzmaximilian@gmail.com
- Signed-off-by: Hans de Goede <hdegoede@redhat.com>
- Patchset: surface-sam
- ---
- drivers/platform/surface/aggregator/Kconfig | 2 +-
- drivers/platform/surface/aggregator/Makefile | 2 +-
- drivers/platform/surface/aggregator/bus.c | 2 +-
- drivers/platform/surface/aggregator/bus.h | 2 +-
- drivers/platform/surface/aggregator/controller.c | 2 +-
- drivers/platform/surface/aggregator/controller.h | 2 +-
- drivers/platform/surface/aggregator/core.c | 2 +-
- drivers/platform/surface/aggregator/ssh_msgb.h | 2 +-
- drivers/platform/surface/aggregator/ssh_packet_layer.c | 2 +-
- drivers/platform/surface/aggregator/ssh_packet_layer.h | 2 +-
- drivers/platform/surface/aggregator/ssh_parser.c | 2 +-
- drivers/platform/surface/aggregator/ssh_parser.h | 2 +-
- drivers/platform/surface/aggregator/ssh_request_layer.c | 2 +-
- drivers/platform/surface/aggregator/ssh_request_layer.h | 2 +-
- drivers/platform/surface/aggregator/trace.h | 2 +-
- include/linux/surface_aggregator/controller.h | 2 +-
- include/linux/surface_aggregator/device.h | 2 +-
- include/linux/surface_aggregator/serial_hub.h | 2 +-
- 18 files changed, 18 insertions(+), 18 deletions(-)
- diff --git a/drivers/platform/surface/aggregator/Kconfig b/drivers/platform/surface/aggregator/Kconfig
- index 3aaeea9f0433..fd6dc452f3e8 100644
- --- a/drivers/platform/surface/aggregator/Kconfig
- +++ b/drivers/platform/surface/aggregator/Kconfig
- @@ -1,5 +1,5 @@
- # SPDX-License-Identifier: GPL-2.0+
- -# Copyright (C) 2019-2020 Maximilian Luz <luzmaximilian@gmail.com>
- +# Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com>
-
- menuconfig SURFACE_AGGREGATOR
- tristate "Microsoft Surface System Aggregator Module Subsystem and Drivers"
- diff --git a/drivers/platform/surface/aggregator/Makefile b/drivers/platform/surface/aggregator/Makefile
- index c112e2c7112b..c8498c41e758 100644
- --- a/drivers/platform/surface/aggregator/Makefile
- +++ b/drivers/platform/surface/aggregator/Makefile
- @@ -1,5 +1,5 @@
- # SPDX-License-Identifier: GPL-2.0+
- -# Copyright (C) 2019-2020 Maximilian Luz <luzmaximilian@gmail.com>
- +# Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com>
-
- # For include/trace/define_trace.h to include trace.h
- CFLAGS_core.o = -I$(src)
- diff --git a/drivers/platform/surface/aggregator/bus.c b/drivers/platform/surface/aggregator/bus.c
- index a9b660af0917..0169677c243e 100644
- --- a/drivers/platform/surface/aggregator/bus.c
- +++ b/drivers/platform/surface/aggregator/bus.c
- @@ -2,7 +2,7 @@
- /*
- * Surface System Aggregator Module bus and device integration.
- *
- - * Copyright (C) 2019-2020 Maximilian Luz <luzmaximilian@gmail.com>
- + * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com>
- */
-
- #include <linux/device.h>
- diff --git a/drivers/platform/surface/aggregator/bus.h b/drivers/platform/surface/aggregator/bus.h
- index 7712baaed6a5..ed032c2cbdb2 100644
- --- a/drivers/platform/surface/aggregator/bus.h
- +++ b/drivers/platform/surface/aggregator/bus.h
- @@ -2,7 +2,7 @@
- /*
- * Surface System Aggregator Module bus and device integration.
- *
- - * Copyright (C) 2019-2020 Maximilian Luz <luzmaximilian@gmail.com>
- + * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com>
- */
-
- #ifndef _SURFACE_AGGREGATOR_BUS_H
- diff --git a/drivers/platform/surface/aggregator/controller.c b/drivers/platform/surface/aggregator/controller.c
- index cedd0f779f7a..6646f4d6e10d 100644
- --- a/drivers/platform/surface/aggregator/controller.c
- +++ b/drivers/platform/surface/aggregator/controller.c
- @@ -2,7 +2,7 @@
- /*
- * Main SSAM/SSH controller structure and functionality.
- *
- - * Copyright (C) 2019-2020 Maximilian Luz <luzmaximilian@gmail.com>
- + * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com>
- */
-
- #include <linux/acpi.h>
- diff --git a/drivers/platform/surface/aggregator/controller.h b/drivers/platform/surface/aggregator/controller.h
- index 8297d34e7489..a0963c3562ff 100644
- --- a/drivers/platform/surface/aggregator/controller.h
- +++ b/drivers/platform/surface/aggregator/controller.h
- @@ -2,7 +2,7 @@
- /*
- * Main SSAM/SSH controller structure and functionality.
- *
- - * Copyright (C) 2019-2020 Maximilian Luz <luzmaximilian@gmail.com>
- + * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com>
- */
-
- #ifndef _SURFACE_AGGREGATOR_CONTROLLER_H
- diff --git a/drivers/platform/surface/aggregator/core.c b/drivers/platform/surface/aggregator/core.c
- index 8dc2c267bcd6..5d780e55f4a1 100644
- --- a/drivers/platform/surface/aggregator/core.c
- +++ b/drivers/platform/surface/aggregator/core.c
- @@ -7,7 +7,7 @@
- * Handles communication via requests as well as enabling, disabling, and
- * relaying of events.
- *
- - * Copyright (C) 2019-2020 Maximilian Luz <luzmaximilian@gmail.com>
- + * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com>
- */
-
- #include <linux/acpi.h>
- diff --git a/drivers/platform/surface/aggregator/ssh_msgb.h b/drivers/platform/surface/aggregator/ssh_msgb.h
- index 1221f642dda1..e562958ffdf0 100644
- --- a/drivers/platform/surface/aggregator/ssh_msgb.h
- +++ b/drivers/platform/surface/aggregator/ssh_msgb.h
- @@ -2,7 +2,7 @@
- /*
- * SSH message builder functions.
- *
- - * Copyright (C) 2019-2020 Maximilian Luz <luzmaximilian@gmail.com>
- + * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com>
- */
-
- #ifndef _SURFACE_AGGREGATOR_SSH_MSGB_H
- diff --git a/drivers/platform/surface/aggregator/ssh_packet_layer.c b/drivers/platform/surface/aggregator/ssh_packet_layer.c
- index 15d96eac6811..5e08049fc3ac 100644
- --- a/drivers/platform/surface/aggregator/ssh_packet_layer.c
- +++ b/drivers/platform/surface/aggregator/ssh_packet_layer.c
- @@ -2,7 +2,7 @@
- /*
- * SSH packet transport layer.
- *
- - * Copyright (C) 2019-2020 Maximilian Luz <luzmaximilian@gmail.com>
- + * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com>
- */
-
- #include <asm/unaligned.h>
- diff --git a/drivers/platform/surface/aggregator/ssh_packet_layer.h b/drivers/platform/surface/aggregator/ssh_packet_layer.h
- index e8757d03f279..2eb329f0b91a 100644
- --- a/drivers/platform/surface/aggregator/ssh_packet_layer.h
- +++ b/drivers/platform/surface/aggregator/ssh_packet_layer.h
- @@ -2,7 +2,7 @@
- /*
- * SSH packet transport layer.
- *
- - * Copyright (C) 2019-2020 Maximilian Luz <luzmaximilian@gmail.com>
- + * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com>
- */
-
- #ifndef _SURFACE_AGGREGATOR_SSH_PACKET_LAYER_H
- diff --git a/drivers/platform/surface/aggregator/ssh_parser.c b/drivers/platform/surface/aggregator/ssh_parser.c
- index e2dead8de94a..b77912f8f13b 100644
- --- a/drivers/platform/surface/aggregator/ssh_parser.c
- +++ b/drivers/platform/surface/aggregator/ssh_parser.c
- @@ -2,7 +2,7 @@
- /*
- * SSH message parser.
- *
- - * Copyright (C) 2019-2020 Maximilian Luz <luzmaximilian@gmail.com>
- + * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com>
- */
-
- #include <asm/unaligned.h>
- diff --git a/drivers/platform/surface/aggregator/ssh_parser.h b/drivers/platform/surface/aggregator/ssh_parser.h
- index 63c38d350988..3bd6e180fd16 100644
- --- a/drivers/platform/surface/aggregator/ssh_parser.h
- +++ b/drivers/platform/surface/aggregator/ssh_parser.h
- @@ -2,7 +2,7 @@
- /*
- * SSH message parser.
- *
- - * Copyright (C) 2019-2020 Maximilian Luz <luzmaximilian@gmail.com>
- + * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com>
- */
-
- #ifndef _SURFACE_AGGREGATOR_SSH_PARSER_H
- diff --git a/drivers/platform/surface/aggregator/ssh_request_layer.c b/drivers/platform/surface/aggregator/ssh_request_layer.c
- index 52a83a8fcf82..bfe1aaf38065 100644
- --- a/drivers/platform/surface/aggregator/ssh_request_layer.c
- +++ b/drivers/platform/surface/aggregator/ssh_request_layer.c
- @@ -2,7 +2,7 @@
- /*
- * SSH request transport layer.
- *
- - * Copyright (C) 2019-2020 Maximilian Luz <luzmaximilian@gmail.com>
- + * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com>
- */
-
- #include <asm/unaligned.h>
- diff --git a/drivers/platform/surface/aggregator/ssh_request_layer.h b/drivers/platform/surface/aggregator/ssh_request_layer.h
- index cb35815858d1..9c3cbae2d4bd 100644
- --- a/drivers/platform/surface/aggregator/ssh_request_layer.h
- +++ b/drivers/platform/surface/aggregator/ssh_request_layer.h
- @@ -2,7 +2,7 @@
- /*
- * SSH request transport layer.
- *
- - * Copyright (C) 2019-2020 Maximilian Luz <luzmaximilian@gmail.com>
- + * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com>
- */
-
- #ifndef _SURFACE_AGGREGATOR_SSH_REQUEST_LAYER_H
- diff --git a/drivers/platform/surface/aggregator/trace.h b/drivers/platform/surface/aggregator/trace.h
- index eb332bb53ae4..de64cf169060 100644
- --- a/drivers/platform/surface/aggregator/trace.h
- +++ b/drivers/platform/surface/aggregator/trace.h
- @@ -2,7 +2,7 @@
- /*
- * Trace points for SSAM/SSH.
- *
- - * Copyright (C) 2020 Maximilian Luz <luzmaximilian@gmail.com>
- + * Copyright (C) 2020-2021 Maximilian Luz <luzmaximilian@gmail.com>
- */
-
- #undef TRACE_SYSTEM
- diff --git a/include/linux/surface_aggregator/controller.h b/include/linux/surface_aggregator/controller.h
- index 7965bdc669c5..068e1982ad37 100644
- --- a/include/linux/surface_aggregator/controller.h
- +++ b/include/linux/surface_aggregator/controller.h
- @@ -6,7 +6,7 @@
- * managing access and communication to and from the SSAM EC, as well as main
- * communication structures and definitions.
- *
- - * Copyright (C) 2019-2020 Maximilian Luz <luzmaximilian@gmail.com>
- + * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com>
- */
-
- #ifndef _LINUX_SURFACE_AGGREGATOR_CONTROLLER_H
- diff --git a/include/linux/surface_aggregator/device.h b/include/linux/surface_aggregator/device.h
- index 6ff9c58b3e17..f636c5310321 100644
- --- a/include/linux/surface_aggregator/device.h
- +++ b/include/linux/surface_aggregator/device.h
- @@ -7,7 +7,7 @@
- * Provides support for non-platform/non-ACPI SSAM clients via dedicated
- * subsystem.
- *
- - * Copyright (C) 2019-2020 Maximilian Luz <luzmaximilian@gmail.com>
- + * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com>
- */
-
- #ifndef _LINUX_SURFACE_AGGREGATOR_DEVICE_H
- diff --git a/include/linux/surface_aggregator/serial_hub.h b/include/linux/surface_aggregator/serial_hub.h
- index 64276fbfa1d5..c3de43edcffa 100644
- --- a/include/linux/surface_aggregator/serial_hub.h
- +++ b/include/linux/surface_aggregator/serial_hub.h
- @@ -6,7 +6,7 @@
- * Surface System Aggregator Module (SSAM). Provides the interface for basic
- * packet- and request-based communication with the SSAM EC via SSH.
- *
- - * Copyright (C) 2019-2020 Maximilian Luz <luzmaximilian@gmail.com>
- + * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com>
- */
-
- #ifndef _LINUX_SURFACE_AGGREGATOR_SERIAL_HUB_H
- --
- 2.32.0
- From 3ef2675ab9aea4ff11b29e0250165bd1cbcdda46 Mon Sep 17 00:00:00 2001
- From: Maximilian Luz <luzmaximilian@gmail.com>
- Date: Fri, 4 Jun 2021 15:47:52 +0200
- Subject: [PATCH] platform/surface: aggregator_cdev: Add support for forwarding
- events to user-space
- Currently, debugging unknown events requires writing a custom driver.
- This is somewhat difficult, slow to adapt, and not entirely
- user-friendly for quickly trying to figure out things on devices of some
- third-party user. We can do better. We already have a user-space
- interface intended for debugging SAM EC requests, so let's add support
- for receiving events to that.
- This commit provides support for receiving events by reading from the
- controller file. It additionally introduces two new IOCTLs to control
- which event categories will be forwarded. Specifically, a user-space
- client can specify which target categories it wants to receive events
- from by registering the corresponding notifier(s) via the IOCTLs and
- after that, read the received events by reading from the controller
- device.
- Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
- Reviewed-by: Hans de Goede <hdegoede@redhat.com>
- Link: https://lore.kernel.org/r/20210604134755.535590-5-luzmaximilian@gmail.com
- Signed-off-by: Hans de Goede <hdegoede@redhat.com>
- Patchset: surface-sam
- ---
- .../userspace-api/ioctl/ioctl-number.rst | 2 +-
- .../surface/surface_aggregator_cdev.c | 460 +++++++++++++++++-
- include/uapi/linux/surface_aggregator/cdev.h | 41 +-
- 3 files changed, 477 insertions(+), 26 deletions(-)
- diff --git a/Documentation/userspace-api/ioctl/ioctl-number.rst b/Documentation/userspace-api/ioctl/ioctl-number.rst
- index 9bfc2b510c64..1409e40e6345 100644
- --- a/Documentation/userspace-api/ioctl/ioctl-number.rst
- +++ b/Documentation/userspace-api/ioctl/ioctl-number.rst
- @@ -325,7 +325,7 @@ Code Seq# Include File Comments
- 0xA3 90-9F linux/dtlk.h
- 0xA4 00-1F uapi/linux/tee.h Generic TEE subsystem
- 0xA4 00-1F uapi/asm/sgx.h <mailto:linux-sgx@vger.kernel.org>
- -0xA5 01 linux/surface_aggregator/cdev.h Microsoft Surface Platform System Aggregator
- +0xA5 01-05 linux/surface_aggregator/cdev.h Microsoft Surface Platform System Aggregator
- <mailto:luzmaximilian@gmail.com>
- 0xA5 20-2F linux/surface_aggregator/dtx.h Microsoft Surface DTX driver
- <mailto:luzmaximilian@gmail.com>
- diff --git a/drivers/platform/surface/surface_aggregator_cdev.c b/drivers/platform/surface/surface_aggregator_cdev.c
- index 79e28fab7e40..dcda377896b7 100644
- --- a/drivers/platform/surface/surface_aggregator_cdev.c
- +++ b/drivers/platform/surface/surface_aggregator_cdev.c
- @@ -3,29 +3,69 @@
- * Provides user-space access to the SSAM EC via the /dev/surface/aggregator
- * misc device. Intended for debugging and development.
- *
- - * Copyright (C) 2020 Maximilian Luz <luzmaximilian@gmail.com>
- + * Copyright (C) 2020-2021 Maximilian Luz <luzmaximilian@gmail.com>
- */
-
- #include <linux/fs.h>
- +#include <linux/ioctl.h>
- #include <linux/kernel.h>
- +#include <linux/kfifo.h>
- #include <linux/kref.h>
- #include <linux/miscdevice.h>
- #include <linux/module.h>
- #include <linux/platform_device.h>
- +#include <linux/poll.h>
- #include <linux/rwsem.h>
- #include <linux/slab.h>
- #include <linux/uaccess.h>
- +#include <linux/vmalloc.h>
-
- #include <linux/surface_aggregator/cdev.h>
- #include <linux/surface_aggregator/controller.h>
- +#include <linux/surface_aggregator/serial_hub.h>
-
- #define SSAM_CDEV_DEVICE_NAME "surface_aggregator_cdev"
-
- +
- +/* -- Main structures. ------------------------------------------------------ */
- +
- +enum ssam_cdev_device_state {
- + SSAM_CDEV_DEVICE_SHUTDOWN_BIT = BIT(0),
- +};
- +
- struct ssam_cdev {
- struct kref kref;
- struct rw_semaphore lock;
- +
- + struct device *dev;
- struct ssam_controller *ctrl;
- struct miscdevice mdev;
- + unsigned long flags;
- +
- + struct rw_semaphore client_lock; /* Guards client list. */
- + struct list_head client_list;
- +};
- +
- +struct ssam_cdev_client;
- +
- +struct ssam_cdev_notifier {
- + struct ssam_cdev_client *client;
- + struct ssam_event_notifier nf;
- +};
- +
- +struct ssam_cdev_client {
- + struct ssam_cdev *cdev;
- + struct list_head node;
- +
- + struct mutex notifier_lock; /* Guards notifier access for registration */
- + struct ssam_cdev_notifier *notifier[SSH_NUM_EVENTS];
- +
- + struct mutex read_lock; /* Guards FIFO buffer read access */
- + struct mutex write_lock; /* Guards FIFO buffer write access */
- + DECLARE_KFIFO(buffer, u8, 4096);
- +
- + wait_queue_head_t waitq;
- + struct fasync_struct *fasync;
- };
-
- static void __ssam_cdev_release(struct kref *kref)
- @@ -47,24 +87,169 @@ static void ssam_cdev_put(struct ssam_cdev *cdev)
- kref_put(&cdev->kref, __ssam_cdev_release);
- }
-
- -static int ssam_cdev_device_open(struct inode *inode, struct file *filp)
- +
- +/* -- Notifier handling. ---------------------------------------------------- */
- +
- +static u32 ssam_cdev_notifier(struct ssam_event_notifier *nf, const struct ssam_event *in)
- {
- - struct miscdevice *mdev = filp->private_data;
- - struct ssam_cdev *cdev = container_of(mdev, struct ssam_cdev, mdev);
- + struct ssam_cdev_notifier *cdev_nf = container_of(nf, struct ssam_cdev_notifier, nf);
- + struct ssam_cdev_client *client = cdev_nf->client;
- + struct ssam_cdev_event event;
- + size_t n = struct_size(&event, data, in->length);
- +
- + /* Translate event. */
- + event.target_category = in->target_category;
- + event.target_id = in->target_id;
- + event.command_id = in->command_id;
- + event.instance_id = in->instance_id;
- + event.length = in->length;
- +
- + mutex_lock(&client->write_lock);
- +
- + /* Make sure we have enough space. */
- + if (kfifo_avail(&client->buffer) < n) {
- + dev_warn(client->cdev->dev,
- + "buffer full, dropping event (tc: %#04x, tid: %#04x, cid: %#04x, iid: %#04x)\n",
- + in->target_category, in->target_id, in->command_id, in->instance_id);
- + mutex_unlock(&client->write_lock);
- + return 0;
- + }
-
- - filp->private_data = ssam_cdev_get(cdev);
- - return stream_open(inode, filp);
- + /* Copy event header and payload. */
- + kfifo_in(&client->buffer, (const u8 *)&event, struct_size(&event, data, 0));
- + kfifo_in(&client->buffer, &in->data[0], in->length);
- +
- + mutex_unlock(&client->write_lock);
- +
- + /* Notify waiting readers. */
- + kill_fasync(&client->fasync, SIGIO, POLL_IN);
- + wake_up_interruptible(&client->waitq);
- +
- + /*
- + * Don't mark events as handled, this is the job of a proper driver and
- + * not the debugging interface.
- + */
- + return 0;
- }
-
- -static int ssam_cdev_device_release(struct inode *inode, struct file *filp)
- +static int ssam_cdev_notifier_register(struct ssam_cdev_client *client, u8 tc, int priority)
- {
- - ssam_cdev_put(filp->private_data);
- - return 0;
- + const u16 rqid = ssh_tc_to_rqid(tc);
- + const u16 event = ssh_rqid_to_event(rqid);
- + struct ssam_cdev_notifier *nf;
- + int status;
- +
- + /* Validate notifier target category. */
- + if (!ssh_rqid_is_event(rqid))
- + return -EINVAL;
- +
- + mutex_lock(&client->notifier_lock);
- +
- + /* Check if the notifier has already been registered. */
- + if (client->notifier[event]) {
- + mutex_unlock(&client->notifier_lock);
- + return -EEXIST;
- + }
- +
- + /* Allocate new notifier. */
- + nf = kzalloc(sizeof(*nf), GFP_KERNEL);
- + if (!nf) {
- + mutex_unlock(&client->notifier_lock);
- + return -ENOMEM;
- + }
- +
- + /*
- + * Create a dummy notifier with the minimal required fields for
- + * observer registration. Note that we can skip fully specifying event
- + * and registry here as we do not need any matching and use silent
- + * registration, which does not enable the corresponding event.
- + */
- + nf->client = client;
- + nf->nf.base.fn = ssam_cdev_notifier;
- + nf->nf.base.priority = priority;
- + nf->nf.event.id.target_category = tc;
- + nf->nf.event.mask = 0; /* Do not do any matching. */
- + nf->nf.flags = SSAM_EVENT_NOTIFIER_OBSERVER;
- +
- + /* Register notifier. */
- + status = ssam_notifier_register(client->cdev->ctrl, &nf->nf);
- + if (status)
- + kfree(nf);
- + else
- + client->notifier[event] = nf;
- +
- + mutex_unlock(&client->notifier_lock);
- + return status;
- }
-
- -static long ssam_cdev_request(struct ssam_cdev *cdev, unsigned long arg)
- +static int ssam_cdev_notifier_unregister(struct ssam_cdev_client *client, u8 tc)
- +{
- + const u16 rqid = ssh_tc_to_rqid(tc);
- + const u16 event = ssh_rqid_to_event(rqid);
- + int status;
- +
- + /* Validate notifier target category. */
- + if (!ssh_rqid_is_event(rqid))
- + return -EINVAL;
- +
- + mutex_lock(&client->notifier_lock);
- +
- + /* Check if the notifier is currently registered. */
- + if (!client->notifier[event]) {
- + mutex_unlock(&client->notifier_lock);
- + return -ENOENT;
- + }
- +
- + /* Unregister and free notifier. */
- + status = ssam_notifier_unregister(client->cdev->ctrl, &client->notifier[event]->nf);
- + kfree(client->notifier[event]);
- + client->notifier[event] = NULL;
- +
- + mutex_unlock(&client->notifier_lock);
- + return status;
- +}
- +
- +static void ssam_cdev_notifier_unregister_all(struct ssam_cdev_client *client)
- +{
- + int i;
- +
- + down_read(&client->cdev->lock);
- +
- + /*
- + * This function may be used during shutdown, thus we need to test for
- + * cdev->ctrl instead of the SSAM_CDEV_DEVICE_SHUTDOWN_BIT bit.
- + */
- + if (client->cdev->ctrl) {
- + for (i = 0; i < SSH_NUM_EVENTS; i++)
- + ssam_cdev_notifier_unregister(client, i + 1);
- +
- + } else {
- + int count = 0;
- +
- + /*
- + * Device has been shut down. Any notifier remaining is a bug,
- + * so warn about that as this would otherwise hardly be
- + * noticeable. Nevertheless, free them as well.
- + */
- + mutex_lock(&client->notifier_lock);
- + for (i = 0; i < SSH_NUM_EVENTS; i++) {
- + count += !!(client->notifier[i]);
- + kfree(client->notifier[i]);
- + client->notifier[i] = NULL;
- + }
- + mutex_unlock(&client->notifier_lock);
- +
- + WARN_ON(count > 0);
- + }
- +
- + up_read(&client->cdev->lock);
- +}
- +
- +
- +/* -- IOCTL functions. ------------------------------------------------------ */
- +
- +static long ssam_cdev_request(struct ssam_cdev_client *client, struct ssam_cdev_request __user *r)
- {
- - struct ssam_cdev_request __user *r;
- struct ssam_cdev_request rqst;
- struct ssam_request spec = {};
- struct ssam_response rsp = {};
- @@ -72,7 +257,6 @@ static long ssam_cdev_request(struct ssam_cdev *cdev, unsigned long arg)
- void __user *rspdata;
- int status = 0, ret = 0, tmp;
-
- - r = (struct ssam_cdev_request __user *)arg;
- ret = copy_struct_from_user(&rqst, sizeof(rqst), r, sizeof(*r));
- if (ret)
- goto out;
- @@ -152,7 +336,7 @@ static long ssam_cdev_request(struct ssam_cdev *cdev, unsigned long arg)
- }
-
- /* Perform request. */
- - status = ssam_request_sync(cdev->ctrl, &spec, &rsp);
- + status = ssam_request_sync(client->cdev->ctrl, &spec, &rsp);
- if (status)
- goto out;
-
- @@ -177,48 +361,247 @@ static long ssam_cdev_request(struct ssam_cdev *cdev, unsigned long arg)
- return ret;
- }
-
- -static long __ssam_cdev_device_ioctl(struct ssam_cdev *cdev, unsigned int cmd,
- +static long ssam_cdev_notif_register(struct ssam_cdev_client *client,
- + const struct ssam_cdev_notifier_desc __user *d)
- +{
- + struct ssam_cdev_notifier_desc desc;
- + long ret;
- +
- + ret = copy_struct_from_user(&desc, sizeof(desc), d, sizeof(*d));
- + if (ret)
- + return ret;
- +
- + return ssam_cdev_notifier_register(client, desc.target_category, desc.priority);
- +}
- +
- +static long ssam_cdev_notif_unregister(struct ssam_cdev_client *client,
- + const struct ssam_cdev_notifier_desc __user *d)
- +{
- + struct ssam_cdev_notifier_desc desc;
- + long ret;
- +
- + ret = copy_struct_from_user(&desc, sizeof(desc), d, sizeof(*d));
- + if (ret)
- + return ret;
- +
- + return ssam_cdev_notifier_unregister(client, desc.target_category);
- +}
- +
- +
- +/* -- File operations. ------------------------------------------------------ */
- +
- +static int ssam_cdev_device_open(struct inode *inode, struct file *filp)
- +{
- + struct miscdevice *mdev = filp->private_data;
- + struct ssam_cdev_client *client;
- + struct ssam_cdev *cdev = container_of(mdev, struct ssam_cdev, mdev);
- +
- + /* Initialize client */
- + client = vzalloc(sizeof(*client));
- + if (!client)
- + return -ENOMEM;
- +
- + client->cdev = ssam_cdev_get(cdev);
- +
- + INIT_LIST_HEAD(&client->node);
- +
- + mutex_init(&client->notifier_lock);
- +
- + mutex_init(&client->read_lock);
- + mutex_init(&client->write_lock);
- + INIT_KFIFO(client->buffer);
- + init_waitqueue_head(&client->waitq);
- +
- + filp->private_data = client;
- +
- + /* Attach client. */
- + down_write(&cdev->client_lock);
- +
- + if (test_bit(SSAM_CDEV_DEVICE_SHUTDOWN_BIT, &cdev->flags)) {
- + up_write(&cdev->client_lock);
- + mutex_destroy(&client->write_lock);
- + mutex_destroy(&client->read_lock);
- + mutex_destroy(&client->notifier_lock);
- + ssam_cdev_put(client->cdev);
- + vfree(client);
- + return -ENODEV;
- + }
- + list_add_tail(&client->node, &cdev->client_list);
- +
- + up_write(&cdev->client_lock);
- +
- + stream_open(inode, filp);
- + return 0;
- +}
- +
- +static int ssam_cdev_device_release(struct inode *inode, struct file *filp)
- +{
- + struct ssam_cdev_client *client = filp->private_data;
- +
- + /* Force-unregister all remaining notifiers of this client. */
- + ssam_cdev_notifier_unregister_all(client);
- +
- + /* Detach client. */
- + down_write(&client->cdev->client_lock);
- + list_del(&client->node);
- + up_write(&client->cdev->client_lock);
- +
- + /* Free client. */
- + mutex_destroy(&client->write_lock);
- + mutex_destroy(&client->read_lock);
- +
- + mutex_destroy(&client->notifier_lock);
- +
- + ssam_cdev_put(client->cdev);
- + vfree(client);
- +
- + return 0;
- +}
- +
- +static long __ssam_cdev_device_ioctl(struct ssam_cdev_client *client, unsigned int cmd,
- unsigned long arg)
- {
- switch (cmd) {
- case SSAM_CDEV_REQUEST:
- - return ssam_cdev_request(cdev, arg);
- + return ssam_cdev_request(client, (struct ssam_cdev_request __user *)arg);
- +
- + case SSAM_CDEV_NOTIF_REGISTER:
- + return ssam_cdev_notif_register(client,
- + (struct ssam_cdev_notifier_desc __user *)arg);
- +
- + case SSAM_CDEV_NOTIF_UNREGISTER:
- + return ssam_cdev_notif_unregister(client,
- + (struct ssam_cdev_notifier_desc __user *)arg);
-
- default:
- return -ENOTTY;
- }
- }
-
- -static long ssam_cdev_device_ioctl(struct file *file, unsigned int cmd,
- - unsigned long arg)
- +static long ssam_cdev_device_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
- {
- - struct ssam_cdev *cdev = file->private_data;
- + struct ssam_cdev_client *client = file->private_data;
- long status;
-
- /* Ensure that controller is valid for as long as we need it. */
- + if (down_read_killable(&client->cdev->lock))
- + return -ERESTARTSYS;
- +
- + if (test_bit(SSAM_CDEV_DEVICE_SHUTDOWN_BIT, &client->cdev->flags)) {
- + up_read(&client->cdev->lock);
- + return -ENODEV;
- + }
- +
- + status = __ssam_cdev_device_ioctl(client, cmd, arg);
- +
- + up_read(&client->cdev->lock);
- + return status;
- +}
- +
- +static ssize_t ssam_cdev_read(struct file *file, char __user *buf, size_t count, loff_t *offs)
- +{
- + struct ssam_cdev_client *client = file->private_data;
- + struct ssam_cdev *cdev = client->cdev;
- + unsigned int copied;
- + int status = 0;
- +
- if (down_read_killable(&cdev->lock))
- return -ERESTARTSYS;
-
- - if (!cdev->ctrl) {
- + /* Make sure we're not shut down. */
- + if (test_bit(SSAM_CDEV_DEVICE_SHUTDOWN_BIT, &cdev->flags)) {
- up_read(&cdev->lock);
- return -ENODEV;
- }
-
- - status = __ssam_cdev_device_ioctl(cdev, cmd, arg);
- + do {
- + /* Check availability, wait if necessary. */
- + if (kfifo_is_empty(&client->buffer)) {
- + up_read(&cdev->lock);
- +
- + if (file->f_flags & O_NONBLOCK)
- + return -EAGAIN;
- +
- + status = wait_event_interruptible(client->waitq,
- + !kfifo_is_empty(&client->buffer) ||
- + test_bit(SSAM_CDEV_DEVICE_SHUTDOWN_BIT,
- + &cdev->flags));
- + if (status < 0)
- + return status;
- +
- + if (down_read_killable(&cdev->lock))
- + return -ERESTARTSYS;
- +
- + /* Need to check that we're not shut down again. */
- + if (test_bit(SSAM_CDEV_DEVICE_SHUTDOWN_BIT, &cdev->flags)) {
- + up_read(&cdev->lock);
- + return -ENODEV;
- + }
- + }
- +
- + /* Try to read from FIFO. */
- + if (mutex_lock_interruptible(&client->read_lock)) {
- + up_read(&cdev->lock);
- + return -ERESTARTSYS;
- + }
- +
- + status = kfifo_to_user(&client->buffer, buf, count, &copied);
- + mutex_unlock(&client->read_lock);
- +
- + if (status < 0) {
- + up_read(&cdev->lock);
- + return status;
- + }
- +
- + /* We might not have gotten anything, check this here. */
- + if (copied == 0 && (file->f_flags & O_NONBLOCK)) {
- + up_read(&cdev->lock);
- + return -EAGAIN;
- + }
- + } while (copied == 0);
-
- up_read(&cdev->lock);
- - return status;
- + return copied;
- +}
- +
- +static __poll_t ssam_cdev_poll(struct file *file, struct poll_table_struct *pt)
- +{
- + struct ssam_cdev_client *client = file->private_data;
- + __poll_t events = 0;
- +
- + if (test_bit(SSAM_CDEV_DEVICE_SHUTDOWN_BIT, &client->cdev->flags))
- + return EPOLLHUP | EPOLLERR;
- +
- + poll_wait(file, &client->waitq, pt);
- +
- + if (!kfifo_is_empty(&client->buffer))
- + events |= EPOLLIN | EPOLLRDNORM;
- +
- + return events;
- +}
- +
- +static int ssam_cdev_fasync(int fd, struct file *file, int on)
- +{
- + struct ssam_cdev_client *client = file->private_data;
- +
- + return fasync_helper(fd, file, on, &client->fasync);
- }
-
- static const struct file_operations ssam_controller_fops = {
- .owner = THIS_MODULE,
- .open = ssam_cdev_device_open,
- .release = ssam_cdev_device_release,
- + .read = ssam_cdev_read,
- + .poll = ssam_cdev_poll,
- + .fasync = ssam_cdev_fasync,
- .unlocked_ioctl = ssam_cdev_device_ioctl,
- .compat_ioctl = ssam_cdev_device_ioctl,
- - .llseek = noop_llseek,
- + .llseek = no_llseek,
- };
-
- +
- +/* -- Device and driver setup ----------------------------------------------- */
- +
- static int ssam_dbg_device_probe(struct platform_device *pdev)
- {
- struct ssam_controller *ctrl;
- @@ -236,6 +619,7 @@ static int ssam_dbg_device_probe(struct platform_device *pdev)
- kref_init(&cdev->kref);
- init_rwsem(&cdev->lock);
- cdev->ctrl = ctrl;
- + cdev->dev = &pdev->dev;
-
- cdev->mdev.parent = &pdev->dev;
- cdev->mdev.minor = MISC_DYNAMIC_MINOR;
- @@ -243,6 +627,9 @@ static int ssam_dbg_device_probe(struct platform_device *pdev)
- cdev->mdev.nodename = "surface/aggregator";
- cdev->mdev.fops = &ssam_controller_fops;
-
- + init_rwsem(&cdev->client_lock);
- + INIT_LIST_HEAD(&cdev->client_list);
- +
- status = misc_register(&cdev->mdev);
- if (status) {
- kfree(cdev);
- @@ -256,8 +643,32 @@ static int ssam_dbg_device_probe(struct platform_device *pdev)
- static int ssam_dbg_device_remove(struct platform_device *pdev)
- {
- struct ssam_cdev *cdev = platform_get_drvdata(pdev);
- + struct ssam_cdev_client *client;
-
- - misc_deregister(&cdev->mdev);
- + /*
- + * Mark device as shut-down. Prevent new clients from being added and
- + * new operations from being executed.
- + */
- + set_bit(SSAM_CDEV_DEVICE_SHUTDOWN_BIT, &cdev->flags);
- +
- + down_write(&cdev->client_lock);
- +
- + /* Remove all notifiers registered by us. */
- + list_for_each_entry(client, &cdev->client_list, node) {
- + ssam_cdev_notifier_unregister_all(client);
- + }
- +
- + /* Wake up async clients. */
- + list_for_each_entry(client, &cdev->client_list, node) {
- + kill_fasync(&client->fasync, SIGIO, POLL_HUP);
- + }
- +
- + /* Wake up blocking clients. */
- + list_for_each_entry(client, &cdev->client_list, node) {
- + wake_up_interruptible(&client->waitq);
- + }
- +
- + up_write(&cdev->client_lock);
-
- /*
- * The controller is only guaranteed to be valid for as long as the
- @@ -266,8 +677,11 @@ static int ssam_dbg_device_remove(struct platform_device *pdev)
- */
- down_write(&cdev->lock);
- cdev->ctrl = NULL;
- + cdev->dev = NULL;
- up_write(&cdev->lock);
-
- + misc_deregister(&cdev->mdev);
- +
- ssam_cdev_put(cdev);
- return 0;
- }
- diff --git a/include/uapi/linux/surface_aggregator/cdev.h b/include/uapi/linux/surface_aggregator/cdev.h
- index fbcce04abfe9..4f393fafc235 100644
- --- a/include/uapi/linux/surface_aggregator/cdev.h
- +++ b/include/uapi/linux/surface_aggregator/cdev.h
- @@ -6,7 +6,7 @@
- * device. This device provides direct user-space access to the SSAM EC.
- * Intended for debugging and development.
- *
- - * Copyright (C) 2020 Maximilian Luz <luzmaximilian@gmail.com>
- + * Copyright (C) 2020-2021 Maximilian Luz <luzmaximilian@gmail.com>
- */
-
- #ifndef _UAPI_LINUX_SURFACE_AGGREGATOR_CDEV_H
- @@ -73,6 +73,43 @@ struct ssam_cdev_request {
- } response;
- } __attribute__((__packed__));
-
- -#define SSAM_CDEV_REQUEST _IOWR(0xA5, 1, struct ssam_cdev_request)
- +/**
- + * struct ssam_cdev_notifier_desc - Notifier descriptor.
- + * @priority: Priority value determining the order in which notifier
- + * callbacks will be called. A higher value means higher
- + * priority, i.e. the associated callback will be executed
- + * earlier than other (lower priority) callbacks.
- + * @target_category: The event target category for which this notifier should
- + * receive events.
- + *
- + * Specifies the notifier that should be registered or unregistered,
- + * specifically with which priority and for which target category of events.
- + */
- +struct ssam_cdev_notifier_desc {
- + __s32 priority;
- + __u8 target_category;
- +} __attribute__((__packed__));
- +
- +/**
- + * struct ssam_cdev_event - SSAM event sent by the EC.
- + * @target_category: Target category of the event source. See &enum ssam_ssh_tc.
- + * @target_id: Target ID of the event source.
- + * @command_id: Command ID of the event.
- + * @instance_id: Instance ID of the event source.
- + * @length: Length of the event payload in bytes.
- + * @data: Event payload data.
- + */
- +struct ssam_cdev_event {
- + __u8 target_category;
- + __u8 target_id;
- + __u8 command_id;
- + __u8 instance_id;
- + __u16 length;
- + __u8 data[];
- +} __attribute__((__packed__));
- +
- +#define SSAM_CDEV_REQUEST _IOWR(0xA5, 1, struct ssam_cdev_request)
- +#define SSAM_CDEV_NOTIF_REGISTER _IOW(0xA5, 2, struct ssam_cdev_notifier_desc)
- +#define SSAM_CDEV_NOTIF_UNREGISTER _IOW(0xA5, 3, struct ssam_cdev_notifier_desc)
-
- #endif /* _UAPI_LINUX_SURFACE_AGGREGATOR_CDEV_H */
- --
- 2.32.0
- From 57beefc4a8f10cc0a26f6d9299fff0574a0c1c95 Mon Sep 17 00:00:00 2001
- From: Maximilian Luz <luzmaximilian@gmail.com>
- Date: Fri, 4 Jun 2021 15:47:53 +0200
- Subject: [PATCH] platform/surface: aggregator_cdev: Allow enabling of events
- from user-space
- While events can already be enabled and disabled via the generic request
- IOCTL, this bypasses the internal reference counting mechanism of the
- controller. Due to that, disabling an event will turn it off regardless
- of any other client having requested said event, which may break
- functionality of that client.
- To solve this, add IOCTLs wrapping the ssam_controller_event_enable()
- and ssam_controller_event_disable() functions, which have been
- previously introduced for this specific purpose.
- Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
- Reviewed-by: Hans de Goede <hdegoede@redhat.com>
- Link: https://lore.kernel.org/r/20210604134755.535590-6-luzmaximilian@gmail.com
- Signed-off-by: Hans de Goede <hdegoede@redhat.com>
- Patchset: surface-sam
- ---
- .../surface/surface_aggregator_cdev.c | 58 +++++++++++++++++++
- include/uapi/linux/surface_aggregator/cdev.h | 32 ++++++++++
- 2 files changed, 90 insertions(+)
- diff --git a/drivers/platform/surface/surface_aggregator_cdev.c b/drivers/platform/surface/surface_aggregator_cdev.c
- index dcda377896b7..7b86b36eaaa0 100644
- --- a/drivers/platform/surface/surface_aggregator_cdev.c
- +++ b/drivers/platform/surface/surface_aggregator_cdev.c
- @@ -387,6 +387,58 @@ static long ssam_cdev_notif_unregister(struct ssam_cdev_client *client,
- return ssam_cdev_notifier_unregister(client, desc.target_category);
- }
-
- +static long ssam_cdev_event_enable(struct ssam_cdev_client *client,
- + const struct ssam_cdev_event_desc __user *d)
- +{
- + struct ssam_cdev_event_desc desc;
- + struct ssam_event_registry reg;
- + struct ssam_event_id id;
- + long ret;
- +
- + /* Read descriptor from user-space. */
- + ret = copy_struct_from_user(&desc, sizeof(desc), d, sizeof(*d));
- + if (ret)
- + return ret;
- +
- + /* Translate descriptor. */
- + reg.target_category = desc.reg.target_category;
- + reg.target_id = desc.reg.target_id;
- + reg.cid_enable = desc.reg.cid_enable;
- + reg.cid_disable = desc.reg.cid_disable;
- +
- + id.target_category = desc.id.target_category;
- + id.instance = desc.id.instance;
- +
- + /* Disable event. */
- + return ssam_controller_event_enable(client->cdev->ctrl, reg, id, desc.flags);
- +}
- +
- +static long ssam_cdev_event_disable(struct ssam_cdev_client *client,
- + const struct ssam_cdev_event_desc __user *d)
- +{
- + struct ssam_cdev_event_desc desc;
- + struct ssam_event_registry reg;
- + struct ssam_event_id id;
- + long ret;
- +
- + /* Read descriptor from user-space. */
- + ret = copy_struct_from_user(&desc, sizeof(desc), d, sizeof(*d));
- + if (ret)
- + return ret;
- +
- + /* Translate descriptor. */
- + reg.target_category = desc.reg.target_category;
- + reg.target_id = desc.reg.target_id;
- + reg.cid_enable = desc.reg.cid_enable;
- + reg.cid_disable = desc.reg.cid_disable;
- +
- + id.target_category = desc.id.target_category;
- + id.instance = desc.id.instance;
- +
- + /* Disable event. */
- + return ssam_controller_event_disable(client->cdev->ctrl, reg, id, desc.flags);
- +}
- +
-
- /* -- File operations. ------------------------------------------------------ */
-
- @@ -473,6 +525,12 @@ static long __ssam_cdev_device_ioctl(struct ssam_cdev_client *client, unsigned i
- return ssam_cdev_notif_unregister(client,
- (struct ssam_cdev_notifier_desc __user *)arg);
-
- + case SSAM_CDEV_EVENT_ENABLE:
- + return ssam_cdev_event_enable(client, (struct ssam_cdev_event_desc __user *)arg);
- +
- + case SSAM_CDEV_EVENT_DISABLE:
- + return ssam_cdev_event_disable(client, (struct ssam_cdev_event_desc __user *)arg);
- +
- default:
- return -ENOTTY;
- }
- diff --git a/include/uapi/linux/surface_aggregator/cdev.h b/include/uapi/linux/surface_aggregator/cdev.h
- index 4f393fafc235..08f46b60b151 100644
- --- a/include/uapi/linux/surface_aggregator/cdev.h
- +++ b/include/uapi/linux/surface_aggregator/cdev.h
- @@ -90,6 +90,36 @@ struct ssam_cdev_notifier_desc {
- __u8 target_category;
- } __attribute__((__packed__));
-
- +/**
- + * struct ssam_cdev_event_desc - Event descriptor.
- + * @reg: Registry via which the event will be enabled/disabled.
- + * @reg.target_category: Target category for the event registry requests.
- + * @reg.target_id: Target ID for the event registry requests.
- + * @reg.cid_enable: Command ID for the event-enable request.
- + * @reg.cid_disable: Command ID for the event-disable request.
- + * @id: ID specifying the event.
- + * @id.target_category: Target category of the event source.
- + * @id.instance: Instance ID of the event source.
- + * @flags: Flags used for enabling the event.
- + *
- + * Specifies which event should be enabled/disabled and how to do that.
- + */
- +struct ssam_cdev_event_desc {
- + struct {
- + __u8 target_category;
- + __u8 target_id;
- + __u8 cid_enable;
- + __u8 cid_disable;
- + } reg;
- +
- + struct {
- + __u8 target_category;
- + __u8 instance;
- + } id;
- +
- + __u8 flags;
- +} __attribute__((__packed__));
- +
- /**
- * struct ssam_cdev_event - SSAM event sent by the EC.
- * @target_category: Target category of the event source. See &enum ssam_ssh_tc.
- @@ -111,5 +141,7 @@ struct ssam_cdev_event {
- #define SSAM_CDEV_REQUEST _IOWR(0xA5, 1, struct ssam_cdev_request)
- #define SSAM_CDEV_NOTIF_REGISTER _IOW(0xA5, 2, struct ssam_cdev_notifier_desc)
- #define SSAM_CDEV_NOTIF_UNREGISTER _IOW(0xA5, 3, struct ssam_cdev_notifier_desc)
- +#define SSAM_CDEV_EVENT_ENABLE _IOW(0xA5, 4, struct ssam_cdev_event_desc)
- +#define SSAM_CDEV_EVENT_DISABLE _IOW(0xA5, 5, struct ssam_cdev_event_desc)
-
- #endif /* _UAPI_LINUX_SURFACE_AGGREGATOR_CDEV_H */
- --
- 2.32.0
- From b26eb043920cf30a9c6dad8b02ebd78adcf1fb2c Mon Sep 17 00:00:00 2001
- From: Maximilian Luz <luzmaximilian@gmail.com>
- Date: Fri, 4 Jun 2021 15:47:54 +0200
- Subject: [PATCH] platform/surface: aggregator_cdev: Add lockdep support
- Mark functions with locking requirements via the corresponding lockdep
- calls for debugging and documentary purposes.
- Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
- Reviewed-by: Hans de Goede <hdegoede@redhat.com>
- Link: https://lore.kernel.org/r/20210604134755.535590-7-luzmaximilian@gmail.com
- Signed-off-by: Hans de Goede <hdegoede@redhat.com>
- Patchset: surface-sam
- ---
- .../platform/surface/surface_aggregator_cdev.c | 16 ++++++++++++++++
- 1 file changed, 16 insertions(+)
- diff --git a/drivers/platform/surface/surface_aggregator_cdev.c b/drivers/platform/surface/surface_aggregator_cdev.c
- index 7b86b36eaaa0..30fb50fde450 100644
- --- a/drivers/platform/surface/surface_aggregator_cdev.c
- +++ b/drivers/platform/surface/surface_aggregator_cdev.c
- @@ -139,6 +139,8 @@ static int ssam_cdev_notifier_register(struct ssam_cdev_client *client, u8 tc, i
- struct ssam_cdev_notifier *nf;
- int status;
-
- + lockdep_assert_held_read(&client->cdev->lock);
- +
- /* Validate notifier target category. */
- if (!ssh_rqid_is_event(rqid))
- return -EINVAL;
- @@ -188,6 +190,8 @@ static int ssam_cdev_notifier_unregister(struct ssam_cdev_client *client, u8 tc)
- const u16 event = ssh_rqid_to_event(rqid);
- int status;
-
- + lockdep_assert_held_read(&client->cdev->lock);
- +
- /* Validate notifier target category. */
- if (!ssh_rqid_is_event(rqid))
- return -EINVAL;
- @@ -257,6 +261,8 @@ static long ssam_cdev_request(struct ssam_cdev_client *client, struct ssam_cdev_
- void __user *rspdata;
- int status = 0, ret = 0, tmp;
-
- + lockdep_assert_held_read(&client->cdev->lock);
- +
- ret = copy_struct_from_user(&rqst, sizeof(rqst), r, sizeof(*r));
- if (ret)
- goto out;
- @@ -367,6 +373,8 @@ static long ssam_cdev_notif_register(struct ssam_cdev_client *client,
- struct ssam_cdev_notifier_desc desc;
- long ret;
-
- + lockdep_assert_held_read(&client->cdev->lock);
- +
- ret = copy_struct_from_user(&desc, sizeof(desc), d, sizeof(*d));
- if (ret)
- return ret;
- @@ -380,6 +388,8 @@ static long ssam_cdev_notif_unregister(struct ssam_cdev_client *client,
- struct ssam_cdev_notifier_desc desc;
- long ret;
-
- + lockdep_assert_held_read(&client->cdev->lock);
- +
- ret = copy_struct_from_user(&desc, sizeof(desc), d, sizeof(*d));
- if (ret)
- return ret;
- @@ -395,6 +405,8 @@ static long ssam_cdev_event_enable(struct ssam_cdev_client *client,
- struct ssam_event_id id;
- long ret;
-
- + lockdep_assert_held_read(&client->cdev->lock);
- +
- /* Read descriptor from user-space. */
- ret = copy_struct_from_user(&desc, sizeof(desc), d, sizeof(*d));
- if (ret)
- @@ -421,6 +433,8 @@ static long ssam_cdev_event_disable(struct ssam_cdev_client *client,
- struct ssam_event_id id;
- long ret;
-
- + lockdep_assert_held_read(&client->cdev->lock);
- +
- /* Read descriptor from user-space. */
- ret = copy_struct_from_user(&desc, sizeof(desc), d, sizeof(*d));
- if (ret)
- @@ -513,6 +527,8 @@ static int ssam_cdev_device_release(struct inode *inode, struct file *filp)
- static long __ssam_cdev_device_ioctl(struct ssam_cdev_client *client, unsigned int cmd,
- unsigned long arg)
- {
- + lockdep_assert_held_read(&client->cdev->lock);
- +
- switch (cmd) {
- case SSAM_CDEV_REQUEST:
- return ssam_cdev_request(client, (struct ssam_cdev_request __user *)arg);
- --
- 2.32.0
- From e41af53103f8422234d1ce3091b496a8a3d9b6e0 Mon Sep 17 00:00:00 2001
- From: Maximilian Luz <luzmaximilian@gmail.com>
- Date: Wed, 2 Jun 2021 20:07:47 +0200
- Subject: [PATCH] docs: driver-api: Update Surface Aggregator user-space
- interface documentation
- Update the controller-device user-space interface (cdev) documentation
- for the newly introduced IOCTLs and event interface.
- Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
- Patchset: surface-sam
- ---
- .../surface_aggregator/clients/cdev.rst | 127 +++++++++++++++++-
- 1 file changed, 122 insertions(+), 5 deletions(-)
- diff --git a/Documentation/driver-api/surface_aggregator/clients/cdev.rst b/Documentation/driver-api/surface_aggregator/clients/cdev.rst
- index 248c1372d879..0134a841a079 100644
- --- a/Documentation/driver-api/surface_aggregator/clients/cdev.rst
- +++ b/Documentation/driver-api/surface_aggregator/clients/cdev.rst
- @@ -1,9 +1,8 @@
- .. SPDX-License-Identifier: GPL-2.0+
-
- -.. |u8| replace:: :c:type:`u8 <u8>`
- -.. |u16| replace:: :c:type:`u16 <u16>`
- .. |ssam_cdev_request| replace:: :c:type:`struct ssam_cdev_request <ssam_cdev_request>`
- .. |ssam_cdev_request_flags| replace:: :c:type:`enum ssam_cdev_request_flags <ssam_cdev_request_flags>`
- +.. |ssam_cdev_event| replace:: :c:type:`struct ssam_cdev_event <ssam_cdev_event>`
-
- ==============================
- User-Space EC Interface (cdev)
- @@ -23,6 +22,40 @@ These IOCTLs and their respective input/output parameter structs are defined in
- A small python library and scripts for accessing this interface can be found
- at https://github.com/linux-surface/surface-aggregator-module/tree/master/scripts/ssam.
-
- +.. contents::
- +
- +
- +Receiving Events
- +================
- +
- +Events can be received by reading from the device-file. The are represented by
- +the |ssam_cdev_event| datatype.
- +
- +Before events are available to be read, however, the desired notifiers must be
- +registered via the ``SSAM_CDEV_NOTIF_REGISTER`` IOCTL. Notifiers are, in
- +essence, callbacks, called when the EC sends an event. They are, in this
- +interface, associated with a specific target category and device-file-instance.
- +They forward any event of this category to the buffer of the corresponding
- +instance, from which it can then be read.
- +
- +Notifiers themselves do not enable events on the EC. Thus, it may additionally
- +be necessary to enable events via the ``SSAM_CDEV_EVENT_ENABLE`` IOCTL. While
- +notifiers work per-client (i.e. per-device-file-instance), events are enabled
- +globally, for the EC and all of its clients (regardless of userspace or
- +non-userspace). The ``SSAM_CDEV_EVENT_ENABLE`` and ``SSAM_CDEV_EVENT_DISABLE``
- +IOCTLs take care of reference counting the events, such that an event is
- +enabled as long as there is a client that has requested it.
- +
- +Note that enabled events are not automatically disabled once the client
- +instance is closed. Therefore any client process (or group of processes) should
- +balance their event enable calls with the corresponding event disable calls. It
- +is, however, perfectly valid to enable and disable events on different client
- +instances. For example, it is valid to set up notifiers and read events on
- +client instance ``A``, enable those events on instance ``B`` (note that these
- +will also be received by A since events are enabled/disabled globally), and
- +after no more events are desired, disable the previously enabled events via
- +instance ``C``.
- +
-
- Controller IOCTLs
- =================
- @@ -45,9 +78,33 @@ The following IOCTLs are provided:
- - ``REQUEST``
- - Perform synchronous SAM request.
-
- + * - ``0xA5``
- + - ``2``
- + - ``W``
- + - ``NOTIF_REGISTER``
- + - Register event notifier.
-
- -``REQUEST``
- ------------
- + * - ``0xA5``
- + - ``3``
- + - ``W``
- + - ``NOTIF_UNREGISTER``
- + - Unregister event notifier.
- +
- + * - ``0xA5``
- + - ``4``
- + - ``W``
- + - ``EVENT_ENABLE``
- + - Enable event source.
- +
- + * - ``0xA5``
- + - ``5``
- + - ``W``
- + - ``EVENT_DISABLE``
- + - Disable event source.
- +
- +
- +``SSAM_CDEV_REQUEST``
- +---------------------
-
- Defined as ``_IOWR(0xA5, 1, struct ssam_cdev_request)``.
-
- @@ -82,6 +139,66 @@ submitted, and completed (i.e. handed back to user-space) successfully from
- inside the IOCTL, but the request ``status`` member may still be negative in
- case the actual execution of the request failed after it has been submitted.
-
- -A full definition of the argument struct is provided below:
- +A full definition of the argument struct is provided below.
- +
- +``SSAM_CDEV_NOTIF_REGISTER``
- +----------------------------
- +
- +Defined as ``_IOW(0xA5, 2, struct ssam_cdev_notifier_desc)``.
- +
- +Register a notifier for the event target category specified in the given
- +notifier description with the specified priority. Notifiers registration is
- +required to receive events, but does not enable events themselves. After a
- +notifier for a specific target category has been registered, all events of that
- +category will be forwarded to the userspace client and can then be read from
- +the device file instance. Note that events may have to be enabled, e.g. via the
- +``SSAM_CDEV_EVENT_ENABLE`` IOCTL, before the EC will send them.
- +
- +Only one notifier can be registered per target category and client instance. If
- +a notifier has already been registered, this IOCTL will fail with ``-EEXIST``.
- +
- +Notifiers will automatically be removed when the device file instance is
- +closed.
- +
- +``SSAM_CDEV_NOTIF_UNREGISTER``
- +------------------------------
- +
- +Defined as ``_IOW(0xA5, 3, struct ssam_cdev_notifier_desc)``.
- +
- +Unregisters the notifier associated with the specified target category. The
- +priority field will be ignored by this IOCTL. If no notifier has been
- +registered for this client instance and the given category, this IOCTL will
- +fail with ``-ENOENT``.
- +
- +``SSAM_CDEV_EVENT_ENABLE``
- +--------------------------
- +
- +Defined as ``_IOW(0xA5, 4, struct ssam_cdev_event_desc)``.
- +
- +Enable the event associated with the given event descriptor.
- +
- +Note that this call will not register a notifier itself, it will only enable
- +events on the controller. If you want to receive events by reading from the
- +device file, you will need to register the corresponding notifier(s) on that
- +instance.
- +
- +Events are not automatically disabled when the device file is closed. This must
- +be done manually, via a call to the ``SSAM_CDEV_EVENT_DISABLE`` IOCTL.
- +
- +``SSAM_CDEV_EVENT_DISABLE``
- +---------------------------
- +
- +Defined as ``_IOW(0xA5, 5, struct ssam_cdev_event_desc)``.
- +
- +Disable the event associated with the given event descriptor.
- +
- +Note that this will not unregister any notifiers. Events may still be received
- +and forwarded to user-space after this call. The only safe way of stopping
- +events from being received is unregistering all previously registered
- +notifiers.
- +
- +
- +Structures and Enums
- +====================
-
- .. kernel-doc:: include/uapi/linux/surface_aggregator/cdev.h
- --
- 2.32.0
- From 60ac33ea0f8194f891b9808d7d7215297de0c63c Mon Sep 17 00:00:00 2001
- From: Maximilian Luz <luzmaximilian@gmail.com>
- Date: Fri, 4 Jun 2021 23:09:06 +0200
- Subject: [PATCH] platform/surface: aggregator: Do not return uninitialized
- value
- The status variable in ssam_nf_refcount_disable_free() is only set when
- the reference count equals zero. Otherwise, it is returned
- uninitialized. Fix this by always initializing status to zero.
- Reported-by: kernel test robot <lkp@intel.com>
- Fixes: 640ee17199e4 ("platform/surface: aggregator: Allow enabling of events without notifiers")
- Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
- Link: https://lore.kernel.org/r/20210604210907.25738-2-luzmaximilian@gmail.com
- Signed-off-by: Hans de Goede <hdegoede@redhat.com>
- Patchset: surface-sam
- ---
- drivers/platform/surface/aggregator/controller.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
- diff --git a/drivers/platform/surface/aggregator/controller.c b/drivers/platform/surface/aggregator/controller.c
- index 6646f4d6e10d..634399387d76 100644
- --- a/drivers/platform/surface/aggregator/controller.c
- +++ b/drivers/platform/surface/aggregator/controller.c
- @@ -2228,7 +2228,7 @@ static int ssam_nf_refcount_disable_free(struct ssam_controller *ctrl,
- const struct ssam_event_registry reg = entry->key.reg;
- const struct ssam_event_id id = entry->key.id;
- struct ssam_nf *nf = &ctrl->cplt.event.notif;
- - int status;
- + int status = 0;
-
- lockdep_assert_held(&nf->lock);
-
- --
- 2.32.0
- From 7640650e61d9f4fba894e321dfe7c9184b3b8a29 Mon Sep 17 00:00:00 2001
- From: Maximilian Luz <luzmaximilian@gmail.com>
- Date: Fri, 4 Jun 2021 23:09:07 +0200
- Subject: [PATCH] platform/surface: aggregator: Drop unnecessary variable
- initialization
- The status variable in ssam_controller_event_disable() is always set, no
- need to initialize it.
- Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
- Link: https://lore.kernel.org/r/20210604210907.25738-3-luzmaximilian@gmail.com
- Signed-off-by: Hans de Goede <hdegoede@redhat.com>
- Patchset: surface-sam
- ---
- drivers/platform/surface/aggregator/controller.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
- diff --git a/drivers/platform/surface/aggregator/controller.c b/drivers/platform/surface/aggregator/controller.c
- index 634399387d76..b8c377b3f932 100644
- --- a/drivers/platform/surface/aggregator/controller.c
- +++ b/drivers/platform/surface/aggregator/controller.c
- @@ -2464,7 +2464,7 @@ int ssam_controller_event_disable(struct ssam_controller *ctrl,
- u16 rqid = ssh_tc_to_rqid(id.target_category);
- struct ssam_nf *nf = &ctrl->cplt.event.notif;
- struct ssam_nf_refcount_entry *entry;
- - int status = 0;
- + int status;
-
- if (!ssh_rqid_is_event(rqid))
- return -EINVAL;
- --
- 2.32.0
- From 4e9280059d06eca593d3da0ccc25250796676908 Mon Sep 17 00:00:00 2001
- From: Baokun Li <libaokun1@huawei.com>
- Date: Wed, 9 Jun 2021 15:26:38 +0800
- Subject: [PATCH] platform/surface: aggregator: Use list_move_tail instead of
- list_del/list_add_tail in ssh_request_layer.c
- Using list_move_tail() instead of list_del() + list_add_tail() in ssh_request_layer.c.
- Reported-by: Hulk Robot <hulkci@huawei.com>
- Signed-off-by: Baokun Li <libaokun1@huawei.com>
- Reviewed-by: Maximilian Luz <luzmaximilian@gmail.com>
- Link: https://lore.kernel.org/r/20210609072638.1358174-1-libaokun1@huawei.com
- Signed-off-by: Hans de Goede <hdegoede@redhat.com>
- Patchset: surface-sam
- ---
- .../platform/surface/aggregator/ssh_request_layer.c | 10 +++-------
- 1 file changed, 3 insertions(+), 7 deletions(-)
- diff --git a/drivers/platform/surface/aggregator/ssh_request_layer.c b/drivers/platform/surface/aggregator/ssh_request_layer.c
- index bfe1aaf38065..790f7f0eee98 100644
- --- a/drivers/platform/surface/aggregator/ssh_request_layer.c
- +++ b/drivers/platform/surface/aggregator/ssh_request_layer.c
- @@ -863,9 +863,7 @@ static void ssh_rtl_timeout_reap(struct work_struct *work)
- clear_bit(SSH_REQUEST_SF_PENDING_BIT, &r->state);
-
- atomic_dec(&rtl->pending.count);
- - list_del(&r->node);
- -
- - list_add_tail(&r->node, &claimed);
- + list_move_tail(&r->node, &claimed);
- }
- spin_unlock(&rtl->pending.lock);
-
- @@ -1204,8 +1202,7 @@ void ssh_rtl_shutdown(struct ssh_rtl *rtl)
- smp_mb__before_atomic();
- clear_bit(SSH_REQUEST_SF_QUEUED_BIT, &r->state);
-
- - list_del(&r->node);
- - list_add_tail(&r->node, &claimed);
- + list_move_tail(&r->node, &claimed);
- }
- spin_unlock(&rtl->queue.lock);
-
- @@ -1238,8 +1235,7 @@ void ssh_rtl_shutdown(struct ssh_rtl *rtl)
- smp_mb__before_atomic();
- clear_bit(SSH_REQUEST_SF_PENDING_BIT, &r->state);
-
- - list_del(&r->node);
- - list_add_tail(&r->node, &claimed);
- + list_move_tail(&r->node, &claimed);
- }
- spin_unlock(&rtl->pending.lock);
- }
- --
- 2.32.0
- From d73fd93fdf881de16ce199225ce97f3c4ce602c5 Mon Sep 17 00:00:00 2001
- From: Baokun Li <libaokun1@huawei.com>
- Date: Wed, 9 Jun 2021 15:24:48 +0800
- Subject: [PATCH] platform/surface: aggregator: Use list_move_tail instead of
- list_del/list_add_tail in ssh_packet_layer.c
- Using list_move_tail() instead of list_del() + list_add_tail() in ssh_packet_layer.c.
- Reported-by: Hulk Robot <hulkci@huawei.com>
- Signed-off-by: Baokun Li <libaokun1@huawei.com>
- Reviewed-by: Maximilian Luz <luzmaximilian@gmail.com>
- Link: https://lore.kernel.org/r/20210609072448.1357524-1-libaokun1@huawei.com
- Signed-off-by: Hans de Goede <hdegoede@redhat.com>
- Patchset: surface-sam
- ---
- drivers/platform/surface/aggregator/ssh_packet_layer.c | 10 +++-------
- 1 file changed, 3 insertions(+), 7 deletions(-)
- diff --git a/drivers/platform/surface/aggregator/ssh_packet_layer.c b/drivers/platform/surface/aggregator/ssh_packet_layer.c
- index 5e08049fc3ac..8a4451c1ffe5 100644
- --- a/drivers/platform/surface/aggregator/ssh_packet_layer.c
- +++ b/drivers/platform/surface/aggregator/ssh_packet_layer.c
- @@ -1567,9 +1567,7 @@ static void ssh_ptl_timeout_reap(struct work_struct *work)
- clear_bit(SSH_PACKET_SF_PENDING_BIT, &p->state);
-
- atomic_dec(&ptl->pending.count);
- - list_del(&p->pending_node);
- -
- - list_add_tail(&p->pending_node, &claimed);
- + list_move_tail(&p->pending_node, &claimed);
- }
-
- spin_unlock(&ptl->pending.lock);
- @@ -1957,8 +1955,7 @@ void ssh_ptl_shutdown(struct ssh_ptl *ptl)
- smp_mb__before_atomic();
- clear_bit(SSH_PACKET_SF_QUEUED_BIT, &p->state);
-
- - list_del(&p->queue_node);
- - list_add_tail(&p->queue_node, &complete_q);
- + list_move_tail(&p->queue_node, &complete_q);
- }
- spin_unlock(&ptl->queue.lock);
-
- @@ -1970,8 +1967,7 @@ void ssh_ptl_shutdown(struct ssh_ptl *ptl)
- smp_mb__before_atomic();
- clear_bit(SSH_PACKET_SF_PENDING_BIT, &p->state);
-
- - list_del(&p->pending_node);
- - list_add_tail(&p->pending_node, &complete_q);
- + list_move_tail(&p->pending_node, &complete_q);
- }
- atomic_set(&ptl->pending.count, 0);
- spin_unlock(&ptl->pending.lock);
- --
- 2.32.0
|