The External-Time-Reference (ETR) clock synchronization interface has been superseded by Server-Time-Protocol (STP). Remove the outdated ETR interface.
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
···11-/*22- * Copyright IBM Corp. 200633- * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)44- */55-#ifndef __S390_ETR_H66-#define __S390_ETR_H77-88-/* ETR attachment control register */99-struct etr_eacr {1010- unsigned int e0 : 1; /* port 0 stepping control */1111- unsigned int e1 : 1; /* port 1 stepping control */1212- unsigned int _pad0 : 5; /* must be 00100 */1313- unsigned int dp : 1; /* data port control */1414- unsigned int p0 : 1; /* port 0 change recognition control */1515- unsigned int p1 : 1; /* port 1 change recognition control */1616- unsigned int _pad1 : 3; /* must be 000 */1717- unsigned int ea : 1; /* ETR alert control */1818- unsigned int es : 1; /* ETR sync check control */1919- unsigned int sl : 1; /* switch to local control */2020-} __attribute__ ((packed));2121-2222-/* Port state returned by steai */2323-enum etr_psc {2424- etr_psc_operational = 0,2525- etr_psc_semi_operational = 1,2626- etr_psc_protocol_error = 4,2727- etr_psc_no_symbols = 8,2828- etr_psc_no_signal = 12,2929- etr_psc_pps_mode = 133030-};3131-3232-/* Logical port state returned by stetr */3333-enum etr_lpsc {3434- etr_lpsc_operational_step = 0,3535- etr_lpsc_operational_alt = 1,3636- etr_lpsc_semi_operational = 2,3737- etr_lpsc_protocol_error = 4,3838- etr_lpsc_no_symbol_sync = 8,3939- etr_lpsc_no_signal = 12,4040- etr_lpsc_pps_mode = 134141-};4242-4343-/* ETR status words */4444-struct etr_esw {4545- struct etr_eacr eacr; /* attachment control register */4646- unsigned int y : 1; /* stepping mode */4747- unsigned int _pad0 : 5; /* must be 00000 */4848- unsigned int p : 1; /* stepping port number */4949- unsigned int q : 1; /* data port number */5050- unsigned int psc0 : 4; /* port 0 state code */5151- unsigned int psc1 : 4; /* port 1 state code */5252-} __attribute__ ((packed));5353-5454-/* Second level data register status word */5555-struct etr_slsw {5656- unsigned int vv1 : 1; /* copy of validity bit data frame 1 */5757- unsigned int vv2 : 1; /* copy of validity bit data frame 2 */5858- unsigned int vv3 : 1; /* copy of validity bit data frame 3 */5959- unsigned int vv4 : 1; /* copy of validity bit data frame 4 */6060- unsigned int _pad0 : 19; /* must by all zeroes */6161- unsigned int n : 1; /* EAF port number */6262- unsigned int v1 : 1; /* validity bit ETR data frame 1 */6363- unsigned int v2 : 1; /* validity bit ETR data frame 2 */6464- unsigned int v3 : 1; /* validity bit ETR data frame 3 */6565- unsigned int v4 : 1; /* validity bit ETR data frame 4 */6666- unsigned int _pad1 : 4; /* must be 0000 */6767-} __attribute__ ((packed));6868-6969-/* ETR data frames */7070-struct etr_edf1 {7171- unsigned int u : 1; /* untuned bit */7272- unsigned int _pad0 : 1; /* must be 0 */7373- unsigned int r : 1; /* service request bit */7474- unsigned int _pad1 : 4; /* must be 0000 */7575- unsigned int a : 1; /* time adjustment bit */7676- unsigned int net_id : 8; /* ETR network id */7777- unsigned int etr_id : 8; /* id of ETR which sends data frames */7878- unsigned int etr_pn : 8; /* port number of ETR output port */7979-} __attribute__ ((packed));8080-8181-struct etr_edf2 {8282- unsigned int etv : 32; /* Upper 32 bits of TOD. */8383-} __attribute__ ((packed));8484-8585-struct etr_edf3 {8686- unsigned int rc : 8; /* failure reason code */8787- unsigned int _pad0 : 3; /* must be 000 */8888- unsigned int c : 1; /* ETR coupled bit */8989- unsigned int tc : 4; /* ETR type code */9090- unsigned int blto : 8; /* biased local time offset */9191- /* (blto - 128) * 15 = minutes */9292- unsigned int buo : 8; /* biased utc offset */9393- /* (buo - 128) = leap seconds */9494-} __attribute__ ((packed));9595-9696-struct etr_edf4 {9797- unsigned int ed : 8; /* ETS device dependent data */9898- unsigned int _pad0 : 1; /* must be 0 */9999- unsigned int buc : 5; /* biased ut1 correction */100100- /* (buc - 16) * 0.1 seconds */101101- unsigned int em : 6; /* ETS error magnitude */102102- unsigned int dc : 6; /* ETS drift code */103103- unsigned int sc : 6; /* ETS steering code */104104-} __attribute__ ((packed));105105-106106-/*107107- * ETR attachment information block, two formats108108- * format 1 has 4 reserved words with a size of 64 bytes109109- * format 2 has 16 reserved words with a size of 96 bytes110110- */111111-struct etr_aib {112112- struct etr_esw esw;113113- struct etr_slsw slsw;114114- unsigned long long tsp;115115- struct etr_edf1 edf1;116116- struct etr_edf2 edf2;117117- struct etr_edf3 edf3;118118- struct etr_edf4 edf4;119119- unsigned int reserved[16];120120-} __attribute__ ((packed,aligned(8)));121121-122122-/* ETR interruption parameter */123123-struct etr_irq_parm {124124- unsigned int _pad0 : 8;125125- unsigned int pc0 : 1; /* port 0 state change */126126- unsigned int pc1 : 1; /* port 1 state change */127127- unsigned int _pad1 : 3;128128- unsigned int eai : 1; /* ETR alert indication */129129- unsigned int _pad2 : 18;130130-} __attribute__ ((packed));131131-132132-/* Inline assembly helper functions */133133-static inline int etr_setr(struct etr_eacr *ctrl)134134-{135135- int rc = -EOPNOTSUPP;136136-137137- asm volatile(138138- " .insn s,0xb2160000,%1\n"139139- "0: la %0,0\n"140140- "1:\n"141141- EX_TABLE(0b,1b)142142- : "+d" (rc) : "Q" (*ctrl));143143- return rc;144144-}145145-146146-/* Stores a format 1 aib with 64 bytes */147147-static inline int etr_stetr(struct etr_aib *aib)148148-{149149- int rc = -EOPNOTSUPP;150150-151151- asm volatile(152152- " .insn s,0xb2170000,%1\n"153153- "0: la %0,0\n"154154- "1:\n"155155- EX_TABLE(0b,1b)156156- : "+d" (rc) : "Q" (*aib));157157- return rc;158158-}159159-160160-/* Stores a format 2 aib with 96 bytes for specified port */161161-static inline int etr_steai(struct etr_aib *aib, unsigned int func)162162-{163163- register unsigned int reg0 asm("0") = func;164164- int rc = -EOPNOTSUPP;165165-166166- asm volatile(167167- " .insn s,0xb2b30000,%1\n"168168- "0: la %0,0\n"169169- "1:\n"170170- EX_TABLE(0b,1b)171171- : "+d" (rc) : "Q" (*aib), "d" (reg0));172172- return rc;173173-}174174-175175-/* Function codes for the steai instruction. */176176-#define ETR_STEAI_STEPPING_PORT 0x10177177-#define ETR_STEAI_ALTERNATE_PORT 0x11178178-#define ETR_STEAI_PORT_0 0x12179179-#define ETR_STEAI_PORT_1 0x13180180-181181-/* Functions needed by the machine check handler */182182-int etr_switch_to_local(void);183183-int etr_sync_check(void);184184-void etr_queue_work(void);185185-186186-/* notifier for syncs */187187-extern struct atomic_notifier_head s390_epoch_delta_notifier;188188-189189-/* STP interruption parameter */190190-struct stp_irq_parm {191191- unsigned int _pad0 : 14;192192- unsigned int tsc : 1; /* Timing status change */193193- unsigned int lac : 1; /* Link availability change */194194- unsigned int tcpc : 1; /* Time control parameter change */195195- unsigned int _pad2 : 15;196196-} __attribute__ ((packed));197197-198198-#define STP_OP_SYNC 1199199-#define STP_OP_CTRL 3200200-201201-struct stp_sstpi {202202- unsigned int rsvd0;203203- unsigned int rsvd1 : 8;204204- unsigned int stratum : 8;205205- unsigned int vbits : 16;206206- unsigned int leaps : 16;207207- unsigned int tmd : 4;208208- unsigned int ctn : 4;209209- unsigned int rsvd2 : 3;210210- unsigned int c : 1;211211- unsigned int tst : 4;212212- unsigned int tzo : 16;213213- unsigned int dsto : 16;214214- unsigned int ctrl : 16;215215- unsigned int rsvd3 : 16;216216- unsigned int tto;217217- unsigned int rsvd4;218218- unsigned int ctnid[3];219219- unsigned int rsvd5;220220- unsigned int todoff[4];221221- unsigned int rsvd6[48];222222-} __attribute__ ((packed));223223-224224-/* Functions needed by the machine check handler */225225-int stp_sync_check(void);226226-int stp_island_check(void);227227-void stp_queue_work(void);228228-229229-#endif /* __S390_ETR_H */
+51
arch/s390/include/asm/stp.h
···11+/*22+ * Copyright IBM Corp. 200633+ * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)44+ */55+#ifndef __S390_STP_H66+#define __S390_STP_H77+88+/* notifier for syncs */99+extern struct atomic_notifier_head s390_epoch_delta_notifier;1010+1111+/* STP interruption parameter */1212+struct stp_irq_parm {1313+ unsigned int _pad0 : 14;1414+ unsigned int tsc : 1; /* Timing status change */1515+ unsigned int lac : 1; /* Link availability change */1616+ unsigned int tcpc : 1; /* Time control parameter change */1717+ unsigned int _pad2 : 15;1818+} __attribute__ ((packed));1919+2020+#define STP_OP_SYNC 12121+#define STP_OP_CTRL 32222+2323+struct stp_sstpi {2424+ unsigned int rsvd0;2525+ unsigned int rsvd1 : 8;2626+ unsigned int stratum : 8;2727+ unsigned int vbits : 16;2828+ unsigned int leaps : 16;2929+ unsigned int tmd : 4;3030+ unsigned int ctn : 4;3131+ unsigned int rsvd2 : 3;3232+ unsigned int c : 1;3333+ unsigned int tst : 4;3434+ unsigned int tzo : 16;3535+ unsigned int dsto : 16;3636+ unsigned int ctrl : 16;3737+ unsigned int rsvd3 : 16;3838+ unsigned int tto;3939+ unsigned int rsvd4;4040+ unsigned int ctnid[3];4141+ unsigned int rsvd5;4242+ unsigned int todoff[4];4343+ unsigned int rsvd6[48];4444+} __attribute__ ((packed));4545+4646+/* Functions needed by the machine check handler */4747+int stp_sync_check(void);4848+int stp_island_check(void);4949+void stp_queue_work(void);5050+5151+#endif /* __S390_STP_H */
+2-11
arch/s390/kernel/nmi.c
···1616#include <linux/module.h>1717#include <asm/lowcore.h>1818#include <asm/smp.h>1919-#include <asm/etr.h>1919+#include <asm/stp.h>2020#include <asm/cputime.h>2121#include <asm/nmi.h>2222#include <asm/crw.h>···2727 unsigned int kill_task : 1;2828 unsigned int channel_report : 1;2929 unsigned int warning : 1;3030- unsigned int etr_queue : 1;3130 unsigned int stp_queue : 1;3231 unsigned long mcck_code;3332};···8182 if (xchg(&mchchk_wng_posted, 1) == 0)8283 kill_cad_pid(SIGPWR, 1);8384 }8484- if (mcck.etr_queue)8585- etr_queue_work();8685 if (mcck.stp_queue)8786 stp_queue_work();8887 if (mcck.kill_task) {···238241239242#define ED_STP_ISLAND 6 /* External damage STP island check */240243#define ED_STP_SYNC 7 /* External damage STP sync check */241241-#define ED_ETR_SYNC 12 /* External damage ETR sync check */242242-#define ED_ETR_SWITCH 13 /* External damage ETR switch to local */243244244245/*245246 * machine check handler.···320325 }321326 if (mci.ed && mci.ec) {322327 /* External damage */323323- if (S390_lowcore.external_damage_code & (1U << ED_ETR_SYNC))324324- mcck->etr_queue |= etr_sync_check();325325- if (S390_lowcore.external_damage_code & (1U << ED_ETR_SWITCH))326326- mcck->etr_queue |= etr_switch_to_local();327328 if (S390_lowcore.external_damage_code & (1U << ED_STP_SYNC))328329 mcck->stp_queue |= stp_sync_check();329330 if (S390_lowcore.external_damage_code & (1U << ED_STP_ISLAND))330331 mcck->stp_queue |= stp_island_check();331331- if (mcck->etr_queue || mcck->stp_queue)332332+ if (mcck->stp_queue)332333 set_cpu_flag(CIF_MCCK_PENDING);333334 }334335 if (mci.se)
+1-988
arch/s390/kernel/time.c
···4646#include <asm/irq.h>4747#include <asm/irq_regs.h>4848#include <asm/vtimer.h>4949-#include <asm/etr.h>4949+#include <asm/stp.h>5050#include <asm/cio.h>5151#include "entry.h"5252···189189 set_clock_comparator(S390_lowcore.clock_comparator);190190}191191192192-static void etr_timing_alert(struct etr_irq_parm *);193192static void stp_timing_alert(struct stp_irq_parm *);194193195194static void timing_alert_interrupt(struct ext_code ext_code,196195 unsigned int param32, unsigned long param64)197196{198197 inc_irq_stat(IRQEXT_TLA);199199- if (param32 & 0x00c40000)200200- etr_timing_alert((struct etr_irq_parm *) ¶m32);201198 if (param32 & 0x00038000)202199 stp_timing_alert((struct stp_irq_parm *) ¶m32);203200}204201205205-static void etr_reset(void);206202static void stp_reset(void);207203208204void read_persistent_clock64(struct timespec64 *ts)···298302void __init time_init(void)299303{300304 /* Reset time synchronization interfaces. */301301- etr_reset();302305 stp_reset();303306304307 /* request the clock comparator external interrupt */···444449 time_sync_wq = create_singlethread_workqueue("timesync");445450}446451447447-/*448448- * External Time Reference (ETR) code.449449- */450450-static int etr_port0_online;451451-static int etr_port1_online;452452-static int etr_steai_available;453453-454454-static int __init early_parse_etr(char *p)455455-{456456- if (strncmp(p, "off", 3) == 0)457457- etr_port0_online = etr_port1_online = 0;458458- else if (strncmp(p, "port0", 5) == 0)459459- etr_port0_online = 1;460460- else if (strncmp(p, "port1", 5) == 0)461461- etr_port1_online = 1;462462- else if (strncmp(p, "on", 2) == 0)463463- etr_port0_online = etr_port1_online = 1;464464- return 0;465465-}466466-early_param("etr", early_parse_etr);467467-468468-enum etr_event {469469- ETR_EVENT_PORT0_CHANGE,470470- ETR_EVENT_PORT1_CHANGE,471471- ETR_EVENT_PORT_ALERT,472472- ETR_EVENT_SYNC_CHECK,473473- ETR_EVENT_SWITCH_LOCAL,474474- ETR_EVENT_UPDATE,475475-};476476-477477-/*478478- * Valid bit combinations of the eacr register are (x = don't care):479479- * e0 e1 dp p0 p1 ea es sl480480- * 0 0 x 0 0 0 0 0 initial, disabled state481481- * 0 0 x 0 1 1 0 0 port 1 online482482- * 0 0 x 1 0 1 0 0 port 0 online483483- * 0 0 x 1 1 1 0 0 both ports online484484- * 0 1 x 0 1 1 0 0 port 1 online and usable, ETR or PPS mode485485- * 0 1 x 0 1 1 0 1 port 1 online, usable and ETR mode486486- * 0 1 x 0 1 1 1 0 port 1 online, usable, PPS mode, in-sync487487- * 0 1 x 0 1 1 1 1 port 1 online, usable, ETR mode, in-sync488488- * 0 1 x 1 1 1 0 0 both ports online, port 1 usable489489- * 0 1 x 1 1 1 1 0 both ports online, port 1 usable, PPS mode, in-sync490490- * 0 1 x 1 1 1 1 1 both ports online, port 1 usable, ETR mode, in-sync491491- * 1 0 x 1 0 1 0 0 port 0 online and usable, ETR or PPS mode492492- * 1 0 x 1 0 1 0 1 port 0 online, usable and ETR mode493493- * 1 0 x 1 0 1 1 0 port 0 online, usable, PPS mode, in-sync494494- * 1 0 x 1 0 1 1 1 port 0 online, usable, ETR mode, in-sync495495- * 1 0 x 1 1 1 0 0 both ports online, port 0 usable496496- * 1 0 x 1 1 1 1 0 both ports online, port 0 usable, PPS mode, in-sync497497- * 1 0 x 1 1 1 1 1 both ports online, port 0 usable, ETR mode, in-sync498498- * 1 1 x 1 1 1 1 0 both ports online & usable, ETR, in-sync499499- * 1 1 x 1 1 1 1 1 both ports online & usable, ETR, in-sync500500- */501501-static struct etr_eacr etr_eacr;502502-static u64 etr_tolec; /* time of last eacr update */503503-static struct etr_aib etr_port0;504504-static int etr_port0_uptodate;505505-static struct etr_aib etr_port1;506506-static int etr_port1_uptodate;507507-static unsigned long etr_events;508508-static struct timer_list etr_timer;509509-510510-static void etr_timeout(unsigned long dummy);511511-static void etr_work_fn(struct work_struct *work);512512-static DEFINE_MUTEX(etr_work_mutex);513513-static DECLARE_WORK(etr_work, etr_work_fn);514514-515515-/*516516- * Reset ETR attachment.517517- */518518-static void etr_reset(void)519519-{520520- etr_eacr = (struct etr_eacr) {521521- .e0 = 0, .e1 = 0, ._pad0 = 4, .dp = 0,522522- .p0 = 0, .p1 = 0, ._pad1 = 0, .ea = 0,523523- .es = 0, .sl = 0 };524524- if (etr_setr(&etr_eacr) == 0) {525525- etr_tolec = get_tod_clock();526526- set_bit(CLOCK_SYNC_HAS_ETR, &clock_sync_flags);527527- if (etr_port0_online && etr_port1_online)528528- set_bit(CLOCK_SYNC_ETR, &clock_sync_flags);529529- } else if (etr_port0_online || etr_port1_online) {530530- pr_warn("The real or virtual hardware system does not provide an ETR interface\n");531531- etr_port0_online = etr_port1_online = 0;532532- }533533-}534534-535535-static int __init etr_init(void)536536-{537537- struct etr_aib aib;538538-539539- if (!test_bit(CLOCK_SYNC_HAS_ETR, &clock_sync_flags))540540- return 0;541541- time_init_wq();542542- /* Check if this machine has the steai instruction. */543543- if (etr_steai(&aib, ETR_STEAI_STEPPING_PORT) == 0)544544- etr_steai_available = 1;545545- setup_timer(&etr_timer, etr_timeout, 0UL);546546- if (etr_port0_online) {547547- set_bit(ETR_EVENT_PORT0_CHANGE, &etr_events);548548- queue_work(time_sync_wq, &etr_work);549549- }550550- if (etr_port1_online) {551551- set_bit(ETR_EVENT_PORT1_CHANGE, &etr_events);552552- queue_work(time_sync_wq, &etr_work);553553- }554554- return 0;555555-}556556-557557-arch_initcall(etr_init);558558-559559-/*560560- * Two sorts of ETR machine checks. The architecture reads:561561- * "When a machine-check niterruption occurs and if a switch-to-local or562562- * ETR-sync-check interrupt request is pending but disabled, this pending563563- * disabled interruption request is indicated and is cleared".564564- * Which means that we can get etr_switch_to_local events from the machine565565- * check handler although the interruption condition is disabled. Lovely..566566- */567567-568568-/*569569- * Switch to local machine check. This is called when the last usable570570- * ETR port goes inactive. After switch to local the clock is not in sync.571571- */572572-int etr_switch_to_local(void)573573-{574574- if (!etr_eacr.sl)575575- return 0;576576- disable_sync_clock(NULL);577577- if (!test_and_set_bit(ETR_EVENT_SWITCH_LOCAL, &etr_events)) {578578- etr_eacr.es = etr_eacr.sl = 0;579579- etr_setr(&etr_eacr);580580- return 1;581581- }582582- return 0;583583-}584584-585585-/*586586- * ETR sync check machine check. This is called when the ETR OTE and the587587- * local clock OTE are farther apart than the ETR sync check tolerance.588588- * After a ETR sync check the clock is not in sync. The machine check589589- * is broadcasted to all cpus at the same time.590590- */591591-int etr_sync_check(void)592592-{593593- if (!etr_eacr.es)594594- return 0;595595- disable_sync_clock(NULL);596596- if (!test_and_set_bit(ETR_EVENT_SYNC_CHECK, &etr_events)) {597597- etr_eacr.es = 0;598598- etr_setr(&etr_eacr);599599- return 1;600600- }601601- return 0;602602-}603603-604604-void etr_queue_work(void)605605-{606606- queue_work(time_sync_wq, &etr_work);607607-}608608-609609-/*610610- * ETR timing alert. There are two causes:611611- * 1) port state change, check the usability of the port612612- * 2) port alert, one of the ETR-data-validity bits (v1-v2 bits of the613613- * sldr-status word) or ETR-data word 1 (edf1) or ETR-data word 3 (edf3)614614- * or ETR-data word 4 (edf4) has changed.615615- */616616-static void etr_timing_alert(struct etr_irq_parm *intparm)617617-{618618- if (intparm->pc0)619619- /* ETR port 0 state change. */620620- set_bit(ETR_EVENT_PORT0_CHANGE, &etr_events);621621- if (intparm->pc1)622622- /* ETR port 1 state change. */623623- set_bit(ETR_EVENT_PORT1_CHANGE, &etr_events);624624- if (intparm->eai)625625- /*626626- * ETR port alert on either port 0, 1 or both.627627- * Both ports are not up-to-date now.628628- */629629- set_bit(ETR_EVENT_PORT_ALERT, &etr_events);630630- queue_work(time_sync_wq, &etr_work);631631-}632632-633633-static void etr_timeout(unsigned long dummy)634634-{635635- set_bit(ETR_EVENT_UPDATE, &etr_events);636636- queue_work(time_sync_wq, &etr_work);637637-}638638-639639-/*640640- * Check if the etr mode is pss.641641- */642642-static inline int etr_mode_is_pps(struct etr_eacr eacr)643643-{644644- return eacr.es && !eacr.sl;645645-}646646-647647-/*648648- * Check if the etr mode is etr.649649- */650650-static inline int etr_mode_is_etr(struct etr_eacr eacr)651651-{652652- return eacr.es && eacr.sl;653653-}654654-655655-/*656656- * Check if the port can be used for TOD synchronization.657657- * For PPS mode the port has to receive OTEs. For ETR mode658658- * the port has to receive OTEs, the ETR stepping bit has to659659- * be zero and the validity bits for data frame 1, 2, and 3660660- * have to be 1.661661- */662662-static int etr_port_valid(struct etr_aib *aib, int port)663663-{664664- unsigned int psc;665665-666666- /* Check that this port is receiving OTEs. */667667- if (aib->tsp == 0)668668- return 0;669669-670670- psc = port ? aib->esw.psc1 : aib->esw.psc0;671671- if (psc == etr_lpsc_pps_mode)672672- return 1;673673- if (psc == etr_lpsc_operational_step)674674- return !aib->esw.y && aib->slsw.v1 &&675675- aib->slsw.v2 && aib->slsw.v3;676676- return 0;677677-}678678-679679-/*680680- * Check if two ports are on the same network.681681- */682682-static int etr_compare_network(struct etr_aib *aib1, struct etr_aib *aib2)683683-{684684- // FIXME: any other fields we have to compare?685685- return aib1->edf1.net_id == aib2->edf1.net_id;686686-}687687-688688-/*689689- * Wrapper for etr_stei that converts physical port states690690- * to logical port states to be consistent with the output691691- * of stetr (see etr_psc vs. etr_lpsc).692692- */693693-static void etr_steai_cv(struct etr_aib *aib, unsigned int func)694694-{695695- BUG_ON(etr_steai(aib, func) != 0);696696- /* Convert port state to logical port state. */697697- if (aib->esw.psc0 == 1)698698- aib->esw.psc0 = 2;699699- else if (aib->esw.psc0 == 0 && aib->esw.p == 0)700700- aib->esw.psc0 = 1;701701- if (aib->esw.psc1 == 1)702702- aib->esw.psc1 = 2;703703- else if (aib->esw.psc1 == 0 && aib->esw.p == 1)704704- aib->esw.psc1 = 1;705705-}706706-707707-/*708708- * Check if the aib a2 is still connected to the same attachment as709709- * aib a1, the etv values differ by one and a2 is valid.710710- */711711-static int etr_aib_follows(struct etr_aib *a1, struct etr_aib *a2, int p)712712-{713713- int state_a1, state_a2;714714-715715- /* Paranoia check: e0/e1 should better be the same. */716716- if (a1->esw.eacr.e0 != a2->esw.eacr.e0 ||717717- a1->esw.eacr.e1 != a2->esw.eacr.e1)718718- return 0;719719-720720- /* Still connected to the same etr ? */721721- state_a1 = p ? a1->esw.psc1 : a1->esw.psc0;722722- state_a2 = p ? a2->esw.psc1 : a2->esw.psc0;723723- if (state_a1 == etr_lpsc_operational_step) {724724- if (state_a2 != etr_lpsc_operational_step ||725725- a1->edf1.net_id != a2->edf1.net_id ||726726- a1->edf1.etr_id != a2->edf1.etr_id ||727727- a1->edf1.etr_pn != a2->edf1.etr_pn)728728- return 0;729729- } else if (state_a2 != etr_lpsc_pps_mode)730730- return 0;731731-732732- /* The ETV value of a2 needs to be ETV of a1 + 1. */733733- if (a1->edf2.etv + 1 != a2->edf2.etv)734734- return 0;735735-736736- if (!etr_port_valid(a2, p))737737- return 0;738738-739739- return 1;740740-}741741-742452struct clock_sync_data {743453 atomic_t cpus;744454 int in_sync;···479779 */480780 fixup_clock_comparator(sync->fixup_cc);481781}482482-483483-/*484484- * Sync the TOD clock using the port referred to by aibp. This port485485- * has to be enabled and the other port has to be disabled. The486486- * last eacr update has to be more than 1.6 seconds in the past.487487- */488488-static int etr_sync_clock(void *data)489489-{490490- static int first;491491- unsigned long long clock, old_clock, clock_delta, delay, delta;492492- struct clock_sync_data *etr_sync;493493- struct etr_aib *sync_port, *aib;494494- struct ptff_qto qto;495495- int port;496496- int rc;497497-498498- etr_sync = data;499499-500500- if (xchg(&first, 1) == 1) {501501- /* Slave */502502- clock_sync_cpu(etr_sync);503503- return 0;504504- }505505-506506- /* Wait until all other cpus entered the sync function. */507507- while (atomic_read(&etr_sync->cpus) != 0)508508- cpu_relax();509509-510510- port = etr_sync->etr_port;511511- aib = etr_sync->etr_aib;512512- sync_port = (port == 0) ? &etr_port0 : &etr_port1;513513- enable_sync_clock();514514-515515- /* Set clock to next OTE. */516516- __ctl_set_bit(14, 21);517517- __ctl_set_bit(0, 29);518518- clock = ((unsigned long long) (aib->edf2.etv + 1)) << 32;519519- old_clock = get_tod_clock();520520- if (set_tod_clock(clock) == 0) {521521- __udelay(1); /* Wait for the clock to start. */522522- __ctl_clear_bit(0, 29);523523- __ctl_clear_bit(14, 21);524524- etr_stetr(aib);525525- /* Adjust Linux timing variables. */526526- delay = (unsigned long long)527527- (aib->edf2.etv - sync_port->edf2.etv) << 32;528528- delta = adjust_time(old_clock, clock, delay);529529- clock_delta = clock - old_clock;530530- atomic_notifier_call_chain(&s390_epoch_delta_notifier, 0,531531- &clock_delta);532532- etr_sync->fixup_cc = delta;533533- fixup_clock_comparator(delta);534534- /* Verify that the clock is properly set. */535535- if (!etr_aib_follows(sync_port, aib, port)) {536536- /* Didn't work. */537537- disable_sync_clock(NULL);538538- etr_sync->in_sync = -EAGAIN;539539- rc = -EAGAIN;540540- } else {541541- if (ptff_query(PTFF_QTO) &&542542- ptff(&qto, sizeof(qto), PTFF_QTO) == 0)543543- /* Update LPAR offset */544544- lpar_offset = qto.tod_epoch_difference;545545- etr_sync->in_sync = 1;546546- rc = 0;547547- }548548- } else {549549- /* Could not set the clock ?!? */550550- __ctl_clear_bit(0, 29);551551- __ctl_clear_bit(14, 21);552552- disable_sync_clock(NULL);553553- etr_sync->in_sync = -EAGAIN;554554- rc = -EAGAIN;555555- }556556- xchg(&first, 0);557557- return rc;558558-}559559-560560-static int etr_sync_clock_stop(struct etr_aib *aib, int port)561561-{562562- struct clock_sync_data etr_sync;563563- struct etr_aib *sync_port;564564- int follows;565565- int rc;566566-567567- /* Check if the current aib is adjacent to the sync port aib. */568568- sync_port = (port == 0) ? &etr_port0 : &etr_port1;569569- follows = etr_aib_follows(sync_port, aib, port);570570- memcpy(sync_port, aib, sizeof(*aib));571571- if (!follows)572572- return -EAGAIN;573573- memset(&etr_sync, 0, sizeof(etr_sync));574574- etr_sync.etr_aib = aib;575575- etr_sync.etr_port = port;576576- get_online_cpus();577577- atomic_set(&etr_sync.cpus, num_online_cpus() - 1);578578- rc = stop_machine(etr_sync_clock, &etr_sync, cpu_online_mask);579579- put_online_cpus();580580- return rc;581581-}582582-583583-/*584584- * Handle the immediate effects of the different events.585585- * The port change event is used for online/offline changes.586586- */587587-static struct etr_eacr etr_handle_events(struct etr_eacr eacr)588588-{589589- if (test_and_clear_bit(ETR_EVENT_SYNC_CHECK, &etr_events))590590- eacr.es = 0;591591- if (test_and_clear_bit(ETR_EVENT_SWITCH_LOCAL, &etr_events))592592- eacr.es = eacr.sl = 0;593593- if (test_and_clear_bit(ETR_EVENT_PORT_ALERT, &etr_events))594594- etr_port0_uptodate = etr_port1_uptodate = 0;595595-596596- if (test_and_clear_bit(ETR_EVENT_PORT0_CHANGE, &etr_events)) {597597- if (eacr.e0)598598- /*599599- * Port change of an enabled port. We have to600600- * assume that this can have caused an stepping601601- * port switch.602602- */603603- etr_tolec = get_tod_clock();604604- eacr.p0 = etr_port0_online;605605- if (!eacr.p0)606606- eacr.e0 = 0;607607- etr_port0_uptodate = 0;608608- }609609- if (test_and_clear_bit(ETR_EVENT_PORT1_CHANGE, &etr_events)) {610610- if (eacr.e1)611611- /*612612- * Port change of an enabled port. We have to613613- * assume that this can have caused an stepping614614- * port switch.615615- */616616- etr_tolec = get_tod_clock();617617- eacr.p1 = etr_port1_online;618618- if (!eacr.p1)619619- eacr.e1 = 0;620620- etr_port1_uptodate = 0;621621- }622622- clear_bit(ETR_EVENT_UPDATE, &etr_events);623623- return eacr;624624-}625625-626626-/*627627- * Set up a timer that expires after the etr_tolec + 1.6 seconds if628628- * one of the ports needs an update.629629- */630630-static void etr_set_tolec_timeout(unsigned long long now)631631-{632632- unsigned long micros;633633-634634- if ((!etr_eacr.p0 || etr_port0_uptodate) &&635635- (!etr_eacr.p1 || etr_port1_uptodate))636636- return;637637- micros = (now > etr_tolec) ? ((now - etr_tolec) >> 12) : 0;638638- micros = (micros > 1600000) ? 0 : 1600000 - micros;639639- mod_timer(&etr_timer, jiffies + (micros * HZ) / 1000000 + 1);640640-}641641-642642-/*643643- * Set up a time that expires after 1/2 second.644644- */645645-static void etr_set_sync_timeout(void)646646-{647647- mod_timer(&etr_timer, jiffies + HZ/2);648648-}649649-650650-/*651651- * Update the aib information for one or both ports.652652- */653653-static struct etr_eacr etr_handle_update(struct etr_aib *aib,654654- struct etr_eacr eacr)655655-{656656- /* With both ports disabled the aib information is useless. */657657- if (!eacr.e0 && !eacr.e1)658658- return eacr;659659-660660- /* Update port0 or port1 with aib stored in etr_work_fn. */661661- if (aib->esw.q == 0) {662662- /* Information for port 0 stored. */663663- if (eacr.p0 && !etr_port0_uptodate) {664664- etr_port0 = *aib;665665- if (etr_port0_online)666666- etr_port0_uptodate = 1;667667- }668668- } else {669669- /* Information for port 1 stored. */670670- if (eacr.p1 && !etr_port1_uptodate) {671671- etr_port1 = *aib;672672- if (etr_port0_online)673673- etr_port1_uptodate = 1;674674- }675675- }676676-677677- /*678678- * Do not try to get the alternate port aib if the clock679679- * is not in sync yet.680680- */681681- if (!eacr.es || !check_sync_clock())682682- return eacr;683683-684684- /*685685- * If steai is available we can get the information about686686- * the other port immediately. If only stetr is available the687687- * data-port bit toggle has to be used.688688- */689689- if (etr_steai_available) {690690- if (eacr.p0 && !etr_port0_uptodate) {691691- etr_steai_cv(&etr_port0, ETR_STEAI_PORT_0);692692- etr_port0_uptodate = 1;693693- }694694- if (eacr.p1 && !etr_port1_uptodate) {695695- etr_steai_cv(&etr_port1, ETR_STEAI_PORT_1);696696- etr_port1_uptodate = 1;697697- }698698- } else {699699- /*700700- * One port was updated above, if the other701701- * port is not uptodate toggle dp bit.702702- */703703- if ((eacr.p0 && !etr_port0_uptodate) ||704704- (eacr.p1 && !etr_port1_uptodate))705705- eacr.dp ^= 1;706706- else707707- eacr.dp = 0;708708- }709709- return eacr;710710-}711711-712712-/*713713- * Write new etr control register if it differs from the current one.714714- * Return 1 if etr_tolec has been updated as well.715715- */716716-static void etr_update_eacr(struct etr_eacr eacr)717717-{718718- int dp_changed;719719-720720- if (memcmp(&etr_eacr, &eacr, sizeof(eacr)) == 0)721721- /* No change, return. */722722- return;723723- /*724724- * The disable of an active port of the change of the data port725725- * bit can/will cause a change in the data port.726726- */727727- dp_changed = etr_eacr.e0 > eacr.e0 || etr_eacr.e1 > eacr.e1 ||728728- (etr_eacr.dp ^ eacr.dp) != 0;729729- etr_eacr = eacr;730730- etr_setr(&etr_eacr);731731- if (dp_changed)732732- etr_tolec = get_tod_clock();733733-}734734-735735-/*736736- * ETR work. In this function you'll find the main logic. In737737- * particular this is the only function that calls etr_update_eacr(),738738- * it "controls" the etr control register.739739- */740740-static void etr_work_fn(struct work_struct *work)741741-{742742- unsigned long long now;743743- struct etr_eacr eacr;744744- struct etr_aib aib;745745- int sync_port;746746-747747- /* prevent multiple execution. */748748- mutex_lock(&etr_work_mutex);749749-750750- /* Create working copy of etr_eacr. */751751- eacr = etr_eacr;752752-753753- /* Check for the different events and their immediate effects. */754754- eacr = etr_handle_events(eacr);755755-756756- /* Check if ETR is supposed to be active. */757757- eacr.ea = eacr.p0 || eacr.p1;758758- if (!eacr.ea) {759759- /* Both ports offline. Reset everything. */760760- eacr.dp = eacr.es = eacr.sl = 0;761761- on_each_cpu(disable_sync_clock, NULL, 1);762762- del_timer_sync(&etr_timer);763763- etr_update_eacr(eacr);764764- goto out_unlock;765765- }766766-767767- /* Store aib to get the current ETR status word. */768768- BUG_ON(etr_stetr(&aib) != 0);769769- etr_port0.esw = etr_port1.esw = aib.esw; /* Copy status word. */770770- now = get_tod_clock();771771-772772- /*773773- * Update the port information if the last stepping port change774774- * or data port change is older than 1.6 seconds.775775- */776776- if (now >= etr_tolec + (1600000 << 12))777777- eacr = etr_handle_update(&aib, eacr);778778-779779- /*780780- * Select ports to enable. The preferred synchronization mode is PPS.781781- * If a port can be enabled depends on a number of things:782782- * 1) The port needs to be online and uptodate. A port is not783783- * disabled just because it is not uptodate, but it is only784784- * enabled if it is uptodate.785785- * 2) The port needs to have the same mode (pps / etr).786786- * 3) The port needs to be usable -> etr_port_valid() == 1787787- * 4) To enable the second port the clock needs to be in sync.788788- * 5) If both ports are useable and are ETR ports, the network id789789- * has to be the same.790790- * The eacr.sl bit is used to indicate etr mode vs. pps mode.791791- */792792- if (eacr.p0 && aib.esw.psc0 == etr_lpsc_pps_mode) {793793- eacr.sl = 0;794794- eacr.e0 = 1;795795- if (!etr_mode_is_pps(etr_eacr))796796- eacr.es = 0;797797- if (!eacr.es || !eacr.p1 || aib.esw.psc1 != etr_lpsc_pps_mode)798798- eacr.e1 = 0;799799- // FIXME: uptodate checks ?800800- else if (etr_port0_uptodate && etr_port1_uptodate)801801- eacr.e1 = 1;802802- sync_port = (etr_port0_uptodate &&803803- etr_port_valid(&etr_port0, 0)) ? 0 : -1;804804- } else if (eacr.p1 && aib.esw.psc1 == etr_lpsc_pps_mode) {805805- eacr.sl = 0;806806- eacr.e0 = 0;807807- eacr.e1 = 1;808808- if (!etr_mode_is_pps(etr_eacr))809809- eacr.es = 0;810810- sync_port = (etr_port1_uptodate &&811811- etr_port_valid(&etr_port1, 1)) ? 1 : -1;812812- } else if (eacr.p0 && aib.esw.psc0 == etr_lpsc_operational_step) {813813- eacr.sl = 1;814814- eacr.e0 = 1;815815- if (!etr_mode_is_etr(etr_eacr))816816- eacr.es = 0;817817- if (!eacr.es || !eacr.p1 ||818818- aib.esw.psc1 != etr_lpsc_operational_alt)819819- eacr.e1 = 0;820820- else if (etr_port0_uptodate && etr_port1_uptodate &&821821- etr_compare_network(&etr_port0, &etr_port1))822822- eacr.e1 = 1;823823- sync_port = (etr_port0_uptodate &&824824- etr_port_valid(&etr_port0, 0)) ? 0 : -1;825825- } else if (eacr.p1 && aib.esw.psc1 == etr_lpsc_operational_step) {826826- eacr.sl = 1;827827- eacr.e0 = 0;828828- eacr.e1 = 1;829829- if (!etr_mode_is_etr(etr_eacr))830830- eacr.es = 0;831831- sync_port = (etr_port1_uptodate &&832832- etr_port_valid(&etr_port1, 1)) ? 1 : -1;833833- } else {834834- /* Both ports not usable. */835835- eacr.es = eacr.sl = 0;836836- sync_port = -1;837837- }838838-839839- /*840840- * If the clock is in sync just update the eacr and return.841841- * If there is no valid sync port wait for a port update.842842- */843843- if ((eacr.es && check_sync_clock()) || sync_port < 0) {844844- etr_update_eacr(eacr);845845- etr_set_tolec_timeout(now);846846- goto out_unlock;847847- }848848-849849- /*850850- * Prepare control register for clock syncing851851- * (reset data port bit, set sync check control.852852- */853853- eacr.dp = 0;854854- eacr.es = 1;855855-856856- /*857857- * Update eacr and try to synchronize the clock. If the update858858- * of eacr caused a stepping port switch (or if we have to859859- * assume that a stepping port switch has occurred) or the860860- * clock syncing failed, reset the sync check control bit861861- * and set up a timer to try again after 0.5 seconds862862- */863863- etr_update_eacr(eacr);864864- if (now < etr_tolec + (1600000 << 12) ||865865- etr_sync_clock_stop(&aib, sync_port) != 0) {866866- /* Sync failed. Try again in 1/2 second. */867867- eacr.es = 0;868868- etr_update_eacr(eacr);869869- etr_set_sync_timeout();870870- } else871871- etr_set_tolec_timeout(now);872872-out_unlock:873873- mutex_unlock(&etr_work_mutex);874874-}875875-876876-/*877877- * Sysfs interface functions878878- */879879-static struct bus_type etr_subsys = {880880- .name = "etr",881881- .dev_name = "etr",882882-};883883-884884-static struct device etr_port0_dev = {885885- .id = 0,886886- .bus = &etr_subsys,887887-};888888-889889-static struct device etr_port1_dev = {890890- .id = 1,891891- .bus = &etr_subsys,892892-};893893-894894-/*895895- * ETR subsys attributes896896- */897897-static ssize_t etr_stepping_port_show(struct device *dev,898898- struct device_attribute *attr,899899- char *buf)900900-{901901- return sprintf(buf, "%i\n", etr_port0.esw.p);902902-}903903-904904-static DEVICE_ATTR(stepping_port, 0400, etr_stepping_port_show, NULL);905905-906906-static ssize_t etr_stepping_mode_show(struct device *dev,907907- struct device_attribute *attr,908908- char *buf)909909-{910910- char *mode_str;911911-912912- if (etr_mode_is_pps(etr_eacr))913913- mode_str = "pps";914914- else if (etr_mode_is_etr(etr_eacr))915915- mode_str = "etr";916916- else917917- mode_str = "local";918918- return sprintf(buf, "%s\n", mode_str);919919-}920920-921921-static DEVICE_ATTR(stepping_mode, 0400, etr_stepping_mode_show, NULL);922922-923923-/*924924- * ETR port attributes925925- */926926-static inline struct etr_aib *etr_aib_from_dev(struct device *dev)927927-{928928- if (dev == &etr_port0_dev)929929- return etr_port0_online ? &etr_port0 : NULL;930930- else931931- return etr_port1_online ? &etr_port1 : NULL;932932-}933933-934934-static ssize_t etr_online_show(struct device *dev,935935- struct device_attribute *attr,936936- char *buf)937937-{938938- unsigned int online;939939-940940- online = (dev == &etr_port0_dev) ? etr_port0_online : etr_port1_online;941941- return sprintf(buf, "%i\n", online);942942-}943943-944944-static ssize_t etr_online_store(struct device *dev,945945- struct device_attribute *attr,946946- const char *buf, size_t count)947947-{948948- unsigned int value;949949-950950- value = simple_strtoul(buf, NULL, 0);951951- if (value != 0 && value != 1)952952- return -EINVAL;953953- if (!test_bit(CLOCK_SYNC_HAS_ETR, &clock_sync_flags))954954- return -EOPNOTSUPP;955955- mutex_lock(&clock_sync_mutex);956956- if (dev == &etr_port0_dev) {957957- if (etr_port0_online == value)958958- goto out; /* Nothing to do. */959959- etr_port0_online = value;960960- if (etr_port0_online && etr_port1_online)961961- set_bit(CLOCK_SYNC_ETR, &clock_sync_flags);962962- else963963- clear_bit(CLOCK_SYNC_ETR, &clock_sync_flags);964964- set_bit(ETR_EVENT_PORT0_CHANGE, &etr_events);965965- queue_work(time_sync_wq, &etr_work);966966- } else {967967- if (etr_port1_online == value)968968- goto out; /* Nothing to do. */969969- etr_port1_online = value;970970- if (etr_port0_online && etr_port1_online)971971- set_bit(CLOCK_SYNC_ETR, &clock_sync_flags);972972- else973973- clear_bit(CLOCK_SYNC_ETR, &clock_sync_flags);974974- set_bit(ETR_EVENT_PORT1_CHANGE, &etr_events);975975- queue_work(time_sync_wq, &etr_work);976976- }977977-out:978978- mutex_unlock(&clock_sync_mutex);979979- return count;980980-}981981-982982-static DEVICE_ATTR(online, 0600, etr_online_show, etr_online_store);983983-984984-static ssize_t etr_stepping_control_show(struct device *dev,985985- struct device_attribute *attr,986986- char *buf)987987-{988988- return sprintf(buf, "%i\n", (dev == &etr_port0_dev) ?989989- etr_eacr.e0 : etr_eacr.e1);990990-}991991-992992-static DEVICE_ATTR(stepping_control, 0400, etr_stepping_control_show, NULL);993993-994994-static ssize_t etr_mode_code_show(struct device *dev,995995- struct device_attribute *attr, char *buf)996996-{997997- if (!etr_port0_online && !etr_port1_online)998998- /* Status word is not uptodate if both ports are offline. */999999- return -ENODATA;10001000- return sprintf(buf, "%i\n", (dev == &etr_port0_dev) ?10011001- etr_port0.esw.psc0 : etr_port0.esw.psc1);10021002-}10031003-10041004-static DEVICE_ATTR(state_code, 0400, etr_mode_code_show, NULL);10051005-10061006-static ssize_t etr_untuned_show(struct device *dev,10071007- struct device_attribute *attr, char *buf)10081008-{10091009- struct etr_aib *aib = etr_aib_from_dev(dev);10101010-10111011- if (!aib || !aib->slsw.v1)10121012- return -ENODATA;10131013- return sprintf(buf, "%i\n", aib->edf1.u);10141014-}10151015-10161016-static DEVICE_ATTR(untuned, 0400, etr_untuned_show, NULL);10171017-10181018-static ssize_t etr_network_id_show(struct device *dev,10191019- struct device_attribute *attr, char *buf)10201020-{10211021- struct etr_aib *aib = etr_aib_from_dev(dev);10221022-10231023- if (!aib || !aib->slsw.v1)10241024- return -ENODATA;10251025- return sprintf(buf, "%i\n", aib->edf1.net_id);10261026-}10271027-10281028-static DEVICE_ATTR(network, 0400, etr_network_id_show, NULL);10291029-10301030-static ssize_t etr_id_show(struct device *dev,10311031- struct device_attribute *attr, char *buf)10321032-{10331033- struct etr_aib *aib = etr_aib_from_dev(dev);10341034-10351035- if (!aib || !aib->slsw.v1)10361036- return -ENODATA;10371037- return sprintf(buf, "%i\n", aib->edf1.etr_id);10381038-}10391039-10401040-static DEVICE_ATTR(id, 0400, etr_id_show, NULL);10411041-10421042-static ssize_t etr_port_number_show(struct device *dev,10431043- struct device_attribute *attr, char *buf)10441044-{10451045- struct etr_aib *aib = etr_aib_from_dev(dev);10461046-10471047- if (!aib || !aib->slsw.v1)10481048- return -ENODATA;10491049- return sprintf(buf, "%i\n", aib->edf1.etr_pn);10501050-}10511051-10521052-static DEVICE_ATTR(port, 0400, etr_port_number_show, NULL);10531053-10541054-static ssize_t etr_coupled_show(struct device *dev,10551055- struct device_attribute *attr, char *buf)10561056-{10571057- struct etr_aib *aib = etr_aib_from_dev(dev);10581058-10591059- if (!aib || !aib->slsw.v3)10601060- return -ENODATA;10611061- return sprintf(buf, "%i\n", aib->edf3.c);10621062-}10631063-10641064-static DEVICE_ATTR(coupled, 0400, etr_coupled_show, NULL);10651065-10661066-static ssize_t etr_local_time_show(struct device *dev,10671067- struct device_attribute *attr, char *buf)10681068-{10691069- struct etr_aib *aib = etr_aib_from_dev(dev);10701070-10711071- if (!aib || !aib->slsw.v3)10721072- return -ENODATA;10731073- return sprintf(buf, "%i\n", aib->edf3.blto);10741074-}10751075-10761076-static DEVICE_ATTR(local_time, 0400, etr_local_time_show, NULL);10771077-10781078-static ssize_t etr_utc_offset_show(struct device *dev,10791079- struct device_attribute *attr, char *buf)10801080-{10811081- struct etr_aib *aib = etr_aib_from_dev(dev);10821082-10831083- if (!aib || !aib->slsw.v3)10841084- return -ENODATA;10851085- return sprintf(buf, "%i\n", aib->edf3.buo);10861086-}10871087-10881088-static DEVICE_ATTR(utc_offset, 0400, etr_utc_offset_show, NULL);10891089-10901090-static struct device_attribute *etr_port_attributes[] = {10911091- &dev_attr_online,10921092- &dev_attr_stepping_control,10931093- &dev_attr_state_code,10941094- &dev_attr_untuned,10951095- &dev_attr_network,10961096- &dev_attr_id,10971097- &dev_attr_port,10981098- &dev_attr_coupled,10991099- &dev_attr_local_time,11001100- &dev_attr_utc_offset,11011101- NULL11021102-};11031103-11041104-static int __init etr_register_port(struct device *dev)11051105-{11061106- struct device_attribute **attr;11071107- int rc;11081108-11091109- rc = device_register(dev);11101110- if (rc)11111111- goto out;11121112- for (attr = etr_port_attributes; *attr; attr++) {11131113- rc = device_create_file(dev, *attr);11141114- if (rc)11151115- goto out_unreg;11161116- }11171117- return 0;11181118-out_unreg:11191119- for (; attr >= etr_port_attributes; attr--)11201120- device_remove_file(dev, *attr);11211121- device_unregister(dev);11221122-out:11231123- return rc;11241124-}11251125-11261126-static void __init etr_unregister_port(struct device *dev)11271127-{11281128- struct device_attribute **attr;11291129-11301130- for (attr = etr_port_attributes; *attr; attr++)11311131- device_remove_file(dev, *attr);11321132- device_unregister(dev);11331133-}11341134-11351135-static int __init etr_init_sysfs(void)11361136-{11371137- int rc;11381138-11391139- rc = subsys_system_register(&etr_subsys, NULL);11401140- if (rc)11411141- goto out;11421142- rc = device_create_file(etr_subsys.dev_root, &dev_attr_stepping_port);11431143- if (rc)11441144- goto out_unreg_subsys;11451145- rc = device_create_file(etr_subsys.dev_root, &dev_attr_stepping_mode);11461146- if (rc)11471147- goto out_remove_stepping_port;11481148- rc = etr_register_port(&etr_port0_dev);11491149- if (rc)11501150- goto out_remove_stepping_mode;11511151- rc = etr_register_port(&etr_port1_dev);11521152- if (rc)11531153- goto out_remove_port0;11541154- return 0;11551155-11561156-out_remove_port0:11571157- etr_unregister_port(&etr_port0_dev);11581158-out_remove_stepping_mode:11591159- device_remove_file(etr_subsys.dev_root, &dev_attr_stepping_mode);11601160-out_remove_stepping_port:11611161- device_remove_file(etr_subsys.dev_root, &dev_attr_stepping_port);11621162-out_unreg_subsys:11631163- bus_unregister(&etr_subsys);11641164-out:11651165- return rc;11661166-}11671167-11681168-device_initcall(etr_init_sysfs);11697821170783/*1171784 * Server Time Protocol (STP) code.