Exemple #1
0
static int s390_next_event(unsigned long delta,
			   struct clock_event_device *evt)
{
	S390_lowcore.clock_comparator = get_tod_clock() + delta;
	set_clock_comparator(S390_lowcore.clock_comparator);
	return 0;
}
Exemple #2
0
void read_persistent_clock64(struct timespec64 *ts)
{
	__u64 clock;

	clock = get_tod_clock() - initial_leap_seconds;
	tod_to_timeval(clock - TOD_UNIX_EPOCH, ts);
}
Exemple #3
0
static int stp_sync_clock(void *data)
{
	static int first;
	unsigned long long old_clock, delta, new_clock, clock_delta;
	struct clock_sync_data *stp_sync;
	struct ptff_qto qto;
	int rc;

	stp_sync = data;

	if (xchg(&first, 1) == 1) {
		/* Slave */
		clock_sync_cpu(stp_sync);
		return 0;
	}

	/* Wait until all other cpus entered the sync function. */
	while (atomic_read(&stp_sync->cpus) != 0)
		cpu_relax();

	enable_sync_clock();

	rc = 0;
	if (stp_info.todoff[0] || stp_info.todoff[1] ||
	    stp_info.todoff[2] || stp_info.todoff[3] ||
	    stp_info.tmd != 2) {
		old_clock = get_tod_clock();
		rc = chsc_sstpc(stp_page, STP_OP_SYNC, 0, &clock_delta);
		if (rc == 0) {
			new_clock = old_clock + clock_delta;
			delta = adjust_time(old_clock, new_clock, 0);
			if (ptff_query(PTFF_QTO) &&
			    ptff(&qto, sizeof(qto), PTFF_QTO) == 0)
				/* Update LPAR offset */
				lpar_offset = qto.tod_epoch_difference;
			atomic_notifier_call_chain(&s390_epoch_delta_notifier,
						   0, &clock_delta);
			fixup_clock_comparator(delta);
			rc = chsc_sstpi(stp_page, &stp_info,
					sizeof(struct stp_sstpi));
			if (rc == 0 && stp_info.tmd != 2)
				rc = -EAGAIN;
		}
	}
	if (rc) {
		disable_sync_clock(NULL);
		stp_sync->in_sync = -EAGAIN;
	} else
		stp_sync->in_sync = 1;
	xchg(&first, 0);
	return 0;
}
Exemple #4
0
cputime64_t arch_cpu_idle_time(int cpu)
{
	struct s390_idle_data *idle = &per_cpu(s390_idle, cpu);
	unsigned long long now, idle_enter, idle_exit;
	unsigned int seq;

	do {
		now = get_tod_clock();
		seq = read_seqcount_begin(&idle->seqcount);
		idle_enter = ACCESS_ONCE(idle->clock_idle_enter);
		idle_exit = ACCESS_ONCE(idle->clock_idle_exit);
	} while (read_seqcount_retry(&idle->seqcount, seq));
	return idle_enter ? ((idle_exit ?: now) - idle_enter) : 0;
}
Exemple #5
0
static ssize_t show_idle_time(struct device *dev,
				struct device_attribute *attr, char *buf)
{
	struct s390_idle_data *idle = &per_cpu(s390_idle, dev->id);
	unsigned long long now, idle_time, idle_enter, idle_exit;
	unsigned int seq;

	do {
		now = get_tod_clock();
		seq = read_seqcount_begin(&idle->seqcount);
		idle_time = ACCESS_ONCE(idle->idle_time);
		idle_enter = ACCESS_ONCE(idle->clock_idle_enter);
		idle_exit = ACCESS_ONCE(idle->clock_idle_exit);
	} while (read_seqcount_retry(&idle->seqcount, seq));
	idle_time += idle_enter ? ((idle_exit ? : now) - idle_enter) : 0;
	return sprintf(buf, "%llu\n", idle_time >> 12);
}
Exemple #6
0
/*
 * The synchronous get_clock function. It will write the current clock
 * value to the clock pointer and return 0 if the clock is in sync with
 * the external time source. If the clock mode is local it will return
 * -EOPNOTSUPP and -EAGAIN if the clock is not in sync with the external
 * reference.
 */
int get_sync_clock(unsigned long long *clock)
{
	atomic_t *sw_ptr;
	unsigned int sw0, sw1;

	sw_ptr = &get_cpu_var(clock_sync_word);
	sw0 = atomic_read(sw_ptr);
	*clock = get_tod_clock();
	sw1 = atomic_read(sw_ptr);
	put_cpu_var(clock_sync_word);
	if (sw0 == sw1 && (sw0 & 0x80000000U))
		/* Success: time is in sync. */
		return 0;
	if (!test_bit(CLOCK_SYNC_HAS_ETR, &clock_sync_flags) &&
	    !test_bit(CLOCK_SYNC_HAS_STP, &clock_sync_flags))
		return -EOPNOTSUPP;
	if (!test_bit(CLOCK_SYNC_ETR, &clock_sync_flags) &&
	    !test_bit(CLOCK_SYNC_STP, &clock_sync_flags))
		return -EACCES;
	return -EAGAIN;
}
Exemple #7
0
/*
 * DESCRIPTION
 *   Frees all ERPs of the current ERP Chain and set the status
 *   of the original CQR either to DASD_CQR_DONE if ERP was successful
 *   or to DASD_CQR_FAILED if ERP was NOT successful.
 *   NOTE: This function is only called if no discipline postaction
 *	   is available
 *
 * PARAMETER
 *   erp		current erp_head
 *
 * RETURN VALUES
 *   cqr		pointer to the original CQR
 */
struct dasd_ccw_req *dasd_default_erp_postaction(struct dasd_ccw_req *cqr)
{
	int success;
	unsigned long long startclk, stopclk;
	struct dasd_device *startdev;

	BUG_ON(cqr->refers == NULL || cqr->function == NULL);

	success = cqr->status == DASD_CQR_DONE;
	startclk = cqr->startclk;
	stopclk = cqr->stopclk;
	startdev = cqr->startdev;

	/* free all ERPs - but NOT the original cqr */
	while (cqr->refers != NULL) {
		struct dasd_ccw_req *refers;

		refers = cqr->refers;
		/* remove the request from the block queue */
		list_del(&cqr->blocklist);
		/* free the finished erp request */
		dasd_free_erp_request(cqr, cqr->memdev);
		cqr = refers;
	}

	/* set corresponding status to original cqr */
	cqr->startclk = startclk;
	cqr->stopclk = stopclk;
	cqr->startdev = startdev;
	if (success)
		cqr->status = DASD_CQR_DONE;
	else {
		cqr->status = DASD_CQR_FAILED;
		cqr->stopclk = get_tod_clock();
	}

	return cqr;

}				/* end default_erp_postaction */
Exemple #8
0
/*
 * dasd_default_erp_action just retries the current cqr
 */
struct dasd_ccw_req *
dasd_default_erp_action(struct dasd_ccw_req *cqr)
{
	struct dasd_device *device;

	device = cqr->startdev;

        /* just retry - there is nothing to save ... I got no sense data.... */
        if (cqr->retries > 0) {
		DBF_DEV_EVENT(DBF_DEBUG, device,
                             "default ERP called (%i retries left)",
                             cqr->retries);
		if (!test_bit(DASD_CQR_VERIFY_PATH, &cqr->flags))
			cqr->lpm = dasd_path_get_opm(device);
		cqr->status = DASD_CQR_FILLED;
        } else {
		pr_err("%s: default ERP has run out of retries and failed\n",
		       dev_name(&device->cdev->dev));
		cqr->status = DASD_CQR_FAILED;
		cqr->stopclk = get_tod_clock();
        }
        return cqr;
}				/* end dasd_default_erp_action */
Exemple #9
0
static cycle_t read_tod_clock(struct clocksource *cs)
{
	return get_tod_clock();
}
Exemple #10
0
void read_persistent_clock(struct timespec *ts)
{
	tod_to_timeval(get_tod_clock() - TOD_UNIX_EPOCH, ts);
}
Exemple #11
0
static void ccw_timeout_log(struct ccw_device *cdev)
{
	struct schib schib;
	struct subchannel *sch;
	struct io_subchannel_private *private;
	union orb *orb;
	int cc;

	sch = to_subchannel(cdev->dev.parent);
	private = to_io_private(sch);
	orb = &private->orb;
	cc = stsch_err(sch->schid, &schib);

	printk(KERN_WARNING "cio: ccw device timeout occurred at %llx, "
	       "device information:\n", get_tod_clock());
	printk(KERN_WARNING "cio: orb:\n");
	print_hex_dump(KERN_WARNING, "cio:  ", DUMP_PREFIX_NONE, 16, 1,
		       orb, sizeof(*orb), 0);
	printk(KERN_WARNING "cio: ccw device bus id: %s\n",
	       dev_name(&cdev->dev));
	printk(KERN_WARNING "cio: subchannel bus id: %s\n",
	       dev_name(&sch->dev));
	printk(KERN_WARNING "cio: subchannel lpm: %02x, opm: %02x, "
	       "vpm: %02x\n", sch->lpm, sch->opm, sch->vpm);

	if (orb->tm.b) {
		printk(KERN_WARNING "cio: orb indicates transport mode\n");
		printk(KERN_WARNING "cio: last tcw:\n");
		print_hex_dump(KERN_WARNING, "cio:  ", DUMP_PREFIX_NONE, 16, 1,
			       (void *)(addr_t)orb->tm.tcw,