Merge branch 'i2c/for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
Pull more i2c updates from Wolfram Sang: "Included are two bugfixes needing some bigger refactoring (sh_mobile: deferred probe with DMA, mv64xxx: fix offload support) and one deprecated driver removal I thought would go in via ppc but I misunderstood. It has a proper ack from BenH" * 'i2c/for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: i2c: sh_mobile: fix uninitialized var when debug is enabled macintosh: therm_pm72: delete deprecated driver i2c: sh_mobile: I2C_SH_MOBILE should depend on HAS_DMA i2c: sh_mobile: rework deferred probing i2c: sh_mobile: refactor DMA setup i2c: mv64xxx: rework offload support to fix several problems i2c: mv64xxx: use BIT() macro for register value definitions
This commit is contained in:
		
						commit
						a4e1328a9d
					
				| @ -753,6 +753,7 @@ config I2C_SH7760 | ||||
| 
 | ||||
| config I2C_SH_MOBILE | ||||
| 	tristate "SuperH Mobile I2C Controller" | ||||
| 	depends on HAS_DMA | ||||
| 	depends on SUPERH || ARCH_SHMOBILE || COMPILE_TEST | ||||
| 	help | ||||
| 	  If you say yes to this option, support will be included for the | ||||
|  | ||||
| @ -30,12 +30,12 @@ | ||||
| #define MV64XXX_I2C_BAUD_DIV_N(val)			(val & 0x7) | ||||
| #define MV64XXX_I2C_BAUD_DIV_M(val)			((val & 0xf) << 3) | ||||
| 
 | ||||
| #define	MV64XXX_I2C_REG_CONTROL_ACK			0x00000004 | ||||
| #define	MV64XXX_I2C_REG_CONTROL_IFLG			0x00000008 | ||||
| #define	MV64XXX_I2C_REG_CONTROL_STOP			0x00000010 | ||||
| #define	MV64XXX_I2C_REG_CONTROL_START			0x00000020 | ||||
| #define	MV64XXX_I2C_REG_CONTROL_TWSIEN			0x00000040 | ||||
| #define	MV64XXX_I2C_REG_CONTROL_INTEN			0x00000080 | ||||
| #define	MV64XXX_I2C_REG_CONTROL_ACK			BIT(2) | ||||
| #define	MV64XXX_I2C_REG_CONTROL_IFLG			BIT(3) | ||||
| #define	MV64XXX_I2C_REG_CONTROL_STOP			BIT(4) | ||||
| #define	MV64XXX_I2C_REG_CONTROL_START			BIT(5) | ||||
| #define	MV64XXX_I2C_REG_CONTROL_TWSIEN			BIT(6) | ||||
| #define	MV64XXX_I2C_REG_CONTROL_INTEN			BIT(7) | ||||
| 
 | ||||
| /* Ctlr status values */ | ||||
| #define	MV64XXX_I2C_STATUS_BUS_ERR			0x00 | ||||
| @ -68,19 +68,17 @@ | ||||
| #define	MV64XXX_I2C_REG_BRIDGE_TIMING			0xe0 | ||||
| 
 | ||||
| /* Bridge Control values */ | ||||
| #define	MV64XXX_I2C_BRIDGE_CONTROL_WR			0x00000001 | ||||
| #define	MV64XXX_I2C_BRIDGE_CONTROL_RD			0x00000002 | ||||
| #define	MV64XXX_I2C_BRIDGE_CONTROL_WR			BIT(0) | ||||
| #define	MV64XXX_I2C_BRIDGE_CONTROL_RD			BIT(1) | ||||
| #define	MV64XXX_I2C_BRIDGE_CONTROL_ADDR_SHIFT		2 | ||||
| #define	MV64XXX_I2C_BRIDGE_CONTROL_ADDR_EXT		0x00001000 | ||||
| #define	MV64XXX_I2C_BRIDGE_CONTROL_ADDR_EXT		BIT(12) | ||||
| #define	MV64XXX_I2C_BRIDGE_CONTROL_TX_SIZE_SHIFT	13 | ||||
| #define	MV64XXX_I2C_BRIDGE_CONTROL_RX_SIZE_SHIFT	16 | ||||
| #define	MV64XXX_I2C_BRIDGE_CONTROL_ENABLE		0x00080000 | ||||
| #define	MV64XXX_I2C_BRIDGE_CONTROL_ENABLE		BIT(19) | ||||
| #define	MV64XXX_I2C_BRIDGE_CONTROL_REPEATED_START	BIT(20) | ||||
| 
 | ||||
| /* Bridge Status values */ | ||||
| #define	MV64XXX_I2C_BRIDGE_STATUS_ERROR			0x00000001 | ||||
| #define	MV64XXX_I2C_STATUS_OFFLOAD_ERROR		0xf0000001 | ||||
| #define	MV64XXX_I2C_STATUS_OFFLOAD_OK			0xf0000000 | ||||
| 
 | ||||
| #define	MV64XXX_I2C_BRIDGE_STATUS_ERROR			BIT(0) | ||||
| 
 | ||||
| /* Driver states */ | ||||
| enum { | ||||
| @ -99,14 +97,12 @@ enum { | ||||
| 	MV64XXX_I2C_ACTION_INVALID, | ||||
| 	MV64XXX_I2C_ACTION_CONTINUE, | ||||
| 	MV64XXX_I2C_ACTION_SEND_RESTART, | ||||
| 	MV64XXX_I2C_ACTION_OFFLOAD_RESTART, | ||||
| 	MV64XXX_I2C_ACTION_SEND_ADDR_1, | ||||
| 	MV64XXX_I2C_ACTION_SEND_ADDR_2, | ||||
| 	MV64XXX_I2C_ACTION_SEND_DATA, | ||||
| 	MV64XXX_I2C_ACTION_RCV_DATA, | ||||
| 	MV64XXX_I2C_ACTION_RCV_DATA_STOP, | ||||
| 	MV64XXX_I2C_ACTION_SEND_STOP, | ||||
| 	MV64XXX_I2C_ACTION_OFFLOAD_SEND_STOP, | ||||
| }; | ||||
| 
 | ||||
| struct mv64xxx_i2c_regs { | ||||
| @ -193,75 +189,6 @@ mv64xxx_i2c_prepare_for_io(struct mv64xxx_i2c_data *drv_data, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static int mv64xxx_i2c_offload_msg(struct mv64xxx_i2c_data *drv_data) | ||||
| { | ||||
| 	unsigned long data_reg_hi = 0; | ||||
| 	unsigned long data_reg_lo = 0; | ||||
| 	unsigned long ctrl_reg; | ||||
| 	struct i2c_msg *msg = drv_data->msgs; | ||||
| 
 | ||||
| 	if (!drv_data->offload_enabled) | ||||
| 		return -EOPNOTSUPP; | ||||
| 
 | ||||
| 	/* Only regular transactions can be offloaded */ | ||||
| 	if ((msg->flags & ~(I2C_M_TEN | I2C_M_RD)) != 0) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	/* Only 1-8 byte transfers can be offloaded */ | ||||
| 	if (msg->len < 1 || msg->len > 8) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	/* Build transaction */ | ||||
| 	ctrl_reg = MV64XXX_I2C_BRIDGE_CONTROL_ENABLE | | ||||
| 		   (msg->addr << MV64XXX_I2C_BRIDGE_CONTROL_ADDR_SHIFT); | ||||
| 
 | ||||
| 	if ((msg->flags & I2C_M_TEN) != 0) | ||||
| 		ctrl_reg |=  MV64XXX_I2C_BRIDGE_CONTROL_ADDR_EXT; | ||||
| 
 | ||||
| 	if ((msg->flags & I2C_M_RD) == 0) { | ||||
| 		u8 local_buf[8] = { 0 }; | ||||
| 
 | ||||
| 		memcpy(local_buf, msg->buf, msg->len); | ||||
| 		data_reg_lo = cpu_to_le32(*((u32 *)local_buf)); | ||||
| 		data_reg_hi = cpu_to_le32(*((u32 *)(local_buf+4))); | ||||
| 
 | ||||
| 		ctrl_reg |= MV64XXX_I2C_BRIDGE_CONTROL_WR | | ||||
| 		    (msg->len - 1) << MV64XXX_I2C_BRIDGE_CONTROL_TX_SIZE_SHIFT; | ||||
| 
 | ||||
| 		writel(data_reg_lo, | ||||
| 			drv_data->reg_base + MV64XXX_I2C_REG_TX_DATA_LO); | ||||
| 		writel(data_reg_hi, | ||||
| 			drv_data->reg_base + MV64XXX_I2C_REG_TX_DATA_HI); | ||||
| 
 | ||||
| 	} else { | ||||
| 		ctrl_reg |= MV64XXX_I2C_BRIDGE_CONTROL_RD | | ||||
| 		    (msg->len - 1) << MV64XXX_I2C_BRIDGE_CONTROL_RX_SIZE_SHIFT; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Execute transaction */ | ||||
| 	writel(ctrl_reg, drv_data->reg_base + MV64XXX_I2C_REG_BRIDGE_CONTROL); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| mv64xxx_i2c_update_offload_data(struct mv64xxx_i2c_data *drv_data) | ||||
| { | ||||
| 	struct i2c_msg *msg = drv_data->msg; | ||||
| 
 | ||||
| 	if (msg->flags & I2C_M_RD) { | ||||
| 		u32 data_reg_lo = readl(drv_data->reg_base + | ||||
| 				MV64XXX_I2C_REG_RX_DATA_LO); | ||||
| 		u32 data_reg_hi = readl(drv_data->reg_base + | ||||
| 				MV64XXX_I2C_REG_RX_DATA_HI); | ||||
| 		u8 local_buf[8] = { 0 }; | ||||
| 
 | ||||
| 		*((u32 *)local_buf) = le32_to_cpu(data_reg_lo); | ||||
| 		*((u32 *)(local_buf+4)) = le32_to_cpu(data_reg_hi); | ||||
| 		memcpy(msg->buf, local_buf, msg->len); | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| /*
 | ||||
|  ***************************************************************************** | ||||
|  * | ||||
| @ -389,16 +316,6 @@ mv64xxx_i2c_fsm(struct mv64xxx_i2c_data *drv_data, u32 status) | ||||
| 		drv_data->rc = -ENXIO; | ||||
| 		break; | ||||
| 
 | ||||
| 	case MV64XXX_I2C_STATUS_OFFLOAD_OK: | ||||
| 		if (drv_data->send_stop || drv_data->aborting) { | ||||
| 			drv_data->action = MV64XXX_I2C_ACTION_OFFLOAD_SEND_STOP; | ||||
| 			drv_data->state = MV64XXX_I2C_STATE_IDLE; | ||||
| 		} else { | ||||
| 			drv_data->action = MV64XXX_I2C_ACTION_OFFLOAD_RESTART; | ||||
| 			drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_RESTART; | ||||
| 		} | ||||
| 		break; | ||||
| 
 | ||||
| 	default: | ||||
| 		dev_err(&drv_data->adapter.dev, | ||||
| 			"mv64xxx_i2c_fsm: Ctlr Error -- state: 0x%x, " | ||||
| @ -419,25 +336,15 @@ static void mv64xxx_i2c_send_start(struct mv64xxx_i2c_data *drv_data) | ||||
| 	drv_data->aborting = 0; | ||||
| 	drv_data->rc = 0; | ||||
| 
 | ||||
| 	/* Can we offload this msg ? */ | ||||
| 	if (mv64xxx_i2c_offload_msg(drv_data) < 0) { | ||||
| 		/* No, switch to standard path */ | ||||
| 		mv64xxx_i2c_prepare_for_io(drv_data, drv_data->msgs); | ||||
| 		writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_START, | ||||
| 			drv_data->reg_base + drv_data->reg_offsets.control); | ||||
| 	} | ||||
| 	mv64xxx_i2c_prepare_for_io(drv_data, drv_data->msgs); | ||||
| 	writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_START, | ||||
| 	       drv_data->reg_base + drv_data->reg_offsets.control); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data) | ||||
| { | ||||
| 	switch(drv_data->action) { | ||||
| 	case MV64XXX_I2C_ACTION_OFFLOAD_RESTART: | ||||
| 		mv64xxx_i2c_update_offload_data(drv_data); | ||||
| 		writel(0, drv_data->reg_base +	MV64XXX_I2C_REG_BRIDGE_CONTROL); | ||||
| 		writel(0, drv_data->reg_base + | ||||
| 			MV64XXX_I2C_REG_BRIDGE_INTR_CAUSE); | ||||
| 		/* FALLTHRU */ | ||||
| 	case MV64XXX_I2C_ACTION_SEND_RESTART: | ||||
| 		/* We should only get here if we have further messages */ | ||||
| 		BUG_ON(drv_data->num_msgs == 0); | ||||
| @ -518,18 +425,73 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data) | ||||
| 		drv_data->block = 0; | ||||
| 		wake_up(&drv_data->waitq); | ||||
| 		break; | ||||
| 
 | ||||
| 	case MV64XXX_I2C_ACTION_OFFLOAD_SEND_STOP: | ||||
| 		mv64xxx_i2c_update_offload_data(drv_data); | ||||
| 		writel(0, drv_data->reg_base +	MV64XXX_I2C_REG_BRIDGE_CONTROL); | ||||
| 		writel(0, drv_data->reg_base + | ||||
| 			MV64XXX_I2C_REG_BRIDGE_INTR_CAUSE); | ||||
| 		drv_data->block = 0; | ||||
| 		wake_up(&drv_data->waitq); | ||||
| 		break; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| mv64xxx_i2c_read_offload_rx_data(struct mv64xxx_i2c_data *drv_data, | ||||
| 				 struct i2c_msg *msg) | ||||
| { | ||||
| 	u32 buf[2]; | ||||
| 
 | ||||
| 	buf[0] = readl(drv_data->reg_base + MV64XXX_I2C_REG_RX_DATA_LO); | ||||
| 	buf[1] = readl(drv_data->reg_base + MV64XXX_I2C_REG_RX_DATA_HI); | ||||
| 
 | ||||
| 	memcpy(msg->buf, buf, msg->len); | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| mv64xxx_i2c_intr_offload(struct mv64xxx_i2c_data *drv_data) | ||||
| { | ||||
| 	u32 cause, status; | ||||
| 
 | ||||
| 	cause = readl(drv_data->reg_base + | ||||
| 		      MV64XXX_I2C_REG_BRIDGE_INTR_CAUSE); | ||||
| 	if (!cause) | ||||
| 		return IRQ_NONE; | ||||
| 
 | ||||
| 	status = readl(drv_data->reg_base + | ||||
| 		       MV64XXX_I2C_REG_BRIDGE_STATUS); | ||||
| 
 | ||||
| 	if (status & MV64XXX_I2C_BRIDGE_STATUS_ERROR) { | ||||
| 		drv_data->rc = -EIO; | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	drv_data->rc = 0; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Transaction is a one message read transaction, read data | ||||
| 	 * for this message. | ||||
| 	 */ | ||||
| 	if (drv_data->num_msgs == 1 && drv_data->msgs[0].flags & I2C_M_RD) { | ||||
| 		mv64xxx_i2c_read_offload_rx_data(drv_data, drv_data->msgs); | ||||
| 		drv_data->msgs++; | ||||
| 		drv_data->num_msgs--; | ||||
| 	} | ||||
| 	/*
 | ||||
| 	 * Transaction is a two messages write/read transaction, read | ||||
| 	 * data for the second (read) message. | ||||
| 	 */ | ||||
| 	else if (drv_data->num_msgs == 2 && | ||||
| 		 !(drv_data->msgs[0].flags & I2C_M_RD) && | ||||
| 		 drv_data->msgs[1].flags & I2C_M_RD) { | ||||
| 		mv64xxx_i2c_read_offload_rx_data(drv_data, drv_data->msgs + 1); | ||||
| 		drv_data->msgs += 2; | ||||
| 		drv_data->num_msgs -= 2; | ||||
| 	} | ||||
| 
 | ||||
| out: | ||||
| 	writel(0, drv_data->reg_base +	MV64XXX_I2C_REG_BRIDGE_CONTROL); | ||||
| 	writel(0, drv_data->reg_base + | ||||
| 	       MV64XXX_I2C_REG_BRIDGE_INTR_CAUSE); | ||||
| 	drv_data->block = 0; | ||||
| 
 | ||||
| 	wake_up(&drv_data->waitq); | ||||
| 
 | ||||
| 	return IRQ_HANDLED; | ||||
| } | ||||
| 
 | ||||
| static irqreturn_t | ||||
| mv64xxx_i2c_intr(int irq, void *dev_id) | ||||
| { | ||||
| @ -540,20 +502,9 @@ mv64xxx_i2c_intr(int irq, void *dev_id) | ||||
| 
 | ||||
| 	spin_lock_irqsave(&drv_data->lock, flags); | ||||
| 
 | ||||
| 	if (drv_data->offload_enabled) { | ||||
| 		while (readl(drv_data->reg_base + | ||||
| 				MV64XXX_I2C_REG_BRIDGE_INTR_CAUSE)) { | ||||
| 			int reg_status = readl(drv_data->reg_base + | ||||
| 					MV64XXX_I2C_REG_BRIDGE_STATUS); | ||||
| 			if (reg_status & MV64XXX_I2C_BRIDGE_STATUS_ERROR) | ||||
| 				status = MV64XXX_I2C_STATUS_OFFLOAD_ERROR; | ||||
| 			else | ||||
| 				status = MV64XXX_I2C_STATUS_OFFLOAD_OK; | ||||
| 			mv64xxx_i2c_fsm(drv_data, status); | ||||
| 			mv64xxx_i2c_do_action(drv_data); | ||||
| 			rc = IRQ_HANDLED; | ||||
| 		} | ||||
| 	} | ||||
| 	if (drv_data->offload_enabled) | ||||
| 		rc = mv64xxx_i2c_intr_offload(drv_data); | ||||
| 
 | ||||
| 	while (readl(drv_data->reg_base + drv_data->reg_offsets.control) & | ||||
| 						MV64XXX_I2C_REG_CONTROL_IFLG) { | ||||
| 		status = readl(drv_data->reg_base + drv_data->reg_offsets.status); | ||||
| @ -635,6 +586,117 @@ mv64xxx_i2c_execute_msg(struct mv64xxx_i2c_data *drv_data, struct i2c_msg *msg, | ||||
| 	return drv_data->rc; | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| mv64xxx_i2c_prepare_tx(struct mv64xxx_i2c_data *drv_data) | ||||
| { | ||||
| 	struct i2c_msg *msg = drv_data->msgs; | ||||
| 	u32 buf[2]; | ||||
| 
 | ||||
| 	memcpy(buf, msg->buf, msg->len); | ||||
| 
 | ||||
| 	writel(buf[0], drv_data->reg_base + MV64XXX_I2C_REG_TX_DATA_LO); | ||||
| 	writel(buf[1], drv_data->reg_base + MV64XXX_I2C_REG_TX_DATA_HI); | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| mv64xxx_i2c_offload_xfer(struct mv64xxx_i2c_data *drv_data) | ||||
| { | ||||
| 	struct i2c_msg *msgs = drv_data->msgs; | ||||
| 	int num = drv_data->num_msgs; | ||||
| 	unsigned long ctrl_reg; | ||||
| 	unsigned long flags; | ||||
| 
 | ||||
| 	spin_lock_irqsave(&drv_data->lock, flags); | ||||
| 
 | ||||
| 	/* Build transaction */ | ||||
| 	ctrl_reg = MV64XXX_I2C_BRIDGE_CONTROL_ENABLE | | ||||
| 		(msgs[0].addr << MV64XXX_I2C_BRIDGE_CONTROL_ADDR_SHIFT); | ||||
| 
 | ||||
| 	if (msgs[0].flags & I2C_M_TEN) | ||||
| 		ctrl_reg |= MV64XXX_I2C_BRIDGE_CONTROL_ADDR_EXT; | ||||
| 
 | ||||
| 	/* Single write message transaction */ | ||||
| 	if (num == 1 && !(msgs[0].flags & I2C_M_RD)) { | ||||
| 		size_t len = msgs[0].len - 1; | ||||
| 
 | ||||
| 		ctrl_reg |= MV64XXX_I2C_BRIDGE_CONTROL_WR | | ||||
| 			(len << MV64XXX_I2C_BRIDGE_CONTROL_TX_SIZE_SHIFT); | ||||
| 		mv64xxx_i2c_prepare_tx(drv_data); | ||||
| 	} | ||||
| 	/* Single read message transaction */ | ||||
| 	else if (num == 1 && msgs[0].flags & I2C_M_RD) { | ||||
| 		size_t len = msgs[0].len - 1; | ||||
| 
 | ||||
| 		ctrl_reg |= MV64XXX_I2C_BRIDGE_CONTROL_RD | | ||||
| 			(len << MV64XXX_I2C_BRIDGE_CONTROL_RX_SIZE_SHIFT); | ||||
| 	} | ||||
| 	/*
 | ||||
| 	 * Transaction with one write and one read message. This is | ||||
| 	 * guaranteed by the mv64xx_i2c_can_offload() checks. | ||||
| 	 */ | ||||
| 	else if (num == 2) { | ||||
| 		size_t lentx = msgs[0].len - 1; | ||||
| 		size_t lenrx = msgs[1].len - 1; | ||||
| 
 | ||||
| 		ctrl_reg |= | ||||
| 			MV64XXX_I2C_BRIDGE_CONTROL_RD | | ||||
| 			MV64XXX_I2C_BRIDGE_CONTROL_WR | | ||||
| 			(lentx << MV64XXX_I2C_BRIDGE_CONTROL_TX_SIZE_SHIFT) | | ||||
| 			(lenrx << MV64XXX_I2C_BRIDGE_CONTROL_RX_SIZE_SHIFT) | | ||||
| 			MV64XXX_I2C_BRIDGE_CONTROL_REPEATED_START; | ||||
| 		mv64xxx_i2c_prepare_tx(drv_data); | ||||
| 	} | ||||
| 
 | ||||
| 	/* Execute transaction */ | ||||
| 	drv_data->block = 1; | ||||
| 	writel(ctrl_reg, drv_data->reg_base + MV64XXX_I2C_REG_BRIDGE_CONTROL); | ||||
| 	spin_unlock_irqrestore(&drv_data->lock, flags); | ||||
| 
 | ||||
| 	mv64xxx_i2c_wait_for_completion(drv_data); | ||||
| 
 | ||||
| 	return drv_data->rc; | ||||
| } | ||||
| 
 | ||||
| static bool | ||||
| mv64xxx_i2c_valid_offload_sz(struct i2c_msg *msg) | ||||
| { | ||||
| 	return msg->len <= 8 && msg->len >= 1; | ||||
| } | ||||
| 
 | ||||
| static bool | ||||
| mv64xxx_i2c_can_offload(struct mv64xxx_i2c_data *drv_data) | ||||
| { | ||||
| 	struct i2c_msg *msgs = drv_data->msgs; | ||||
| 	int num = drv_data->num_msgs; | ||||
| 
 | ||||
| 	return false; | ||||
| 
 | ||||
| 	if (!drv_data->offload_enabled) | ||||
| 		return false; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * We can offload a transaction consisting of a single | ||||
| 	 * message, as long as the message has a length between 1 and | ||||
| 	 * 8 bytes. | ||||
| 	 */ | ||||
| 	if (num == 1 && mv64xxx_i2c_valid_offload_sz(msgs)) | ||||
| 		return true; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * We can offload a transaction consisting of two messages, if | ||||
| 	 * the first is a write and a second is a read, and both have | ||||
| 	 * a length between 1 and 8 bytes. | ||||
| 	 */ | ||||
| 	if (num == 2 && | ||||
| 	    mv64xxx_i2c_valid_offload_sz(msgs) && | ||||
| 	    mv64xxx_i2c_valid_offload_sz(msgs + 1) && | ||||
| 	    !(msgs[0].flags & I2C_M_RD) && | ||||
| 	    msgs[1].flags & I2C_M_RD) | ||||
| 		return true; | ||||
| 
 | ||||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  ***************************************************************************** | ||||
|  * | ||||
| @ -658,7 +720,11 @@ mv64xxx_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) | ||||
| 	drv_data->msgs = msgs; | ||||
| 	drv_data->num_msgs = num; | ||||
| 
 | ||||
| 	rc = mv64xxx_i2c_execute_msg(drv_data, &msgs[0], num == 1); | ||||
| 	if (mv64xxx_i2c_can_offload(drv_data)) | ||||
| 		rc = mv64xxx_i2c_offload_xfer(drv_data); | ||||
| 	else | ||||
| 		rc = mv64xxx_i2c_execute_msg(drv_data, &msgs[0], num == 1); | ||||
| 
 | ||||
| 	if (rc < 0) | ||||
| 		ret = rc; | ||||
| 
 | ||||
|  | ||||
| @ -140,6 +140,7 @@ struct sh_mobile_i2c_data { | ||||
| 	int sr; | ||||
| 	bool send_stop; | ||||
| 
 | ||||
| 	struct resource *res; | ||||
| 	struct dma_chan *dma_tx; | ||||
| 	struct dma_chan *dma_rx; | ||||
| 	struct scatterlist sg; | ||||
| @ -539,6 +540,42 @@ static void sh_mobile_i2c_dma_callback(void *data) | ||||
| 	iic_set_clr(pd, ICIC, 0, ICIC_TDMAE | ICIC_RDMAE); | ||||
| } | ||||
| 
 | ||||
| static struct dma_chan *sh_mobile_i2c_request_dma_chan(struct device *dev, | ||||
| 				enum dma_transfer_direction dir, dma_addr_t port_addr) | ||||
| { | ||||
| 	struct dma_chan *chan; | ||||
| 	struct dma_slave_config cfg; | ||||
| 	char *chan_name = dir == DMA_MEM_TO_DEV ? "tx" : "rx"; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	chan = dma_request_slave_channel_reason(dev, chan_name); | ||||
| 	if (IS_ERR(chan)) { | ||||
| 		ret = PTR_ERR(chan); | ||||
| 		dev_dbg(dev, "request_channel failed for %s (%d)\n", chan_name, ret); | ||||
| 		return chan; | ||||
| 	} | ||||
| 
 | ||||
| 	memset(&cfg, 0, sizeof(cfg)); | ||||
| 	cfg.direction = dir; | ||||
| 	if (dir == DMA_MEM_TO_DEV) { | ||||
| 		cfg.dst_addr = port_addr; | ||||
| 		cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; | ||||
| 	} else { | ||||
| 		cfg.src_addr = port_addr; | ||||
| 		cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; | ||||
| 	} | ||||
| 
 | ||||
| 	ret = dmaengine_slave_config(chan, &cfg); | ||||
| 	if (ret) { | ||||
| 		dev_dbg(dev, "slave_config failed for %s (%d)\n", chan_name, ret); | ||||
| 		dma_release_channel(chan); | ||||
| 		return ERR_PTR(ret); | ||||
| 	} | ||||
| 
 | ||||
| 	dev_dbg(dev, "got DMA channel for %s\n", chan_name); | ||||
| 	return chan; | ||||
| } | ||||
| 
 | ||||
| static void sh_mobile_i2c_xfer_dma(struct sh_mobile_i2c_data *pd) | ||||
| { | ||||
| 	bool read = pd->msg->flags & I2C_M_RD; | ||||
| @ -548,7 +585,16 @@ static void sh_mobile_i2c_xfer_dma(struct sh_mobile_i2c_data *pd) | ||||
| 	dma_addr_t dma_addr; | ||||
| 	dma_cookie_t cookie; | ||||
| 
 | ||||
| 	if (!chan) | ||||
| 	if (PTR_ERR(chan) == -EPROBE_DEFER) { | ||||
| 		if (read) | ||||
| 			chan = pd->dma_rx = sh_mobile_i2c_request_dma_chan(pd->dev, DMA_DEV_TO_MEM, | ||||
| 									   pd->res->start + ICDR); | ||||
| 		else | ||||
| 			chan = pd->dma_tx = sh_mobile_i2c_request_dma_chan(pd->dev, DMA_MEM_TO_DEV, | ||||
| 									   pd->res->start + ICDR); | ||||
| 	} | ||||
| 
 | ||||
| 	if (IS_ERR(chan)) | ||||
| 		return; | ||||
| 
 | ||||
| 	dma_addr = dma_map_single(chan->device->dev, pd->msg->buf, pd->msg->len, dir); | ||||
| @ -747,56 +793,16 @@ static const struct of_device_id sh_mobile_i2c_dt_ids[] = { | ||||
| }; | ||||
| MODULE_DEVICE_TABLE(of, sh_mobile_i2c_dt_ids); | ||||
| 
 | ||||
| static int sh_mobile_i2c_request_dma_chan(struct device *dev, enum dma_transfer_direction dir, | ||||
| 					  dma_addr_t port_addr, struct dma_chan **chan_ptr) | ||||
| { | ||||
| 	struct dma_chan *chan; | ||||
| 	struct dma_slave_config cfg; | ||||
| 	char *chan_name = dir == DMA_MEM_TO_DEV ? "tx" : "rx"; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	*chan_ptr = NULL; | ||||
| 
 | ||||
| 	chan = dma_request_slave_channel_reason(dev, chan_name); | ||||
| 	if (IS_ERR(chan)) { | ||||
| 		ret = PTR_ERR(chan); | ||||
| 		dev_dbg(dev, "request_channel failed for %s (%d)\n", chan_name, ret); | ||||
| 		return ret; | ||||
| 	} | ||||
| 
 | ||||
| 	memset(&cfg, 0, sizeof(cfg)); | ||||
| 	cfg.direction = dir; | ||||
| 	if (dir == DMA_MEM_TO_DEV) { | ||||
| 		cfg.dst_addr = port_addr; | ||||
| 		cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; | ||||
| 	} else { | ||||
| 		cfg.src_addr = port_addr; | ||||
| 		cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; | ||||
| 	} | ||||
| 
 | ||||
| 	ret = dmaengine_slave_config(chan, &cfg); | ||||
| 	if (ret) { | ||||
| 		dev_dbg(dev, "slave_config failed for %s (%d)\n", chan_name, ret); | ||||
| 		dma_release_channel(chan); | ||||
| 		return ret; | ||||
| 	} | ||||
| 
 | ||||
| 	*chan_ptr = chan; | ||||
| 
 | ||||
| 	dev_dbg(dev, "got DMA channel for %s\n", chan_name); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static void sh_mobile_i2c_release_dma(struct sh_mobile_i2c_data *pd) | ||||
| { | ||||
| 	if (pd->dma_tx) { | ||||
| 	if (!IS_ERR(pd->dma_tx)) { | ||||
| 		dma_release_channel(pd->dma_tx); | ||||
| 		pd->dma_tx = NULL; | ||||
| 		pd->dma_tx = ERR_PTR(-EPROBE_DEFER); | ||||
| 	} | ||||
| 
 | ||||
| 	if (pd->dma_rx) { | ||||
| 	if (!IS_ERR(pd->dma_rx)) { | ||||
| 		dma_release_channel(pd->dma_rx); | ||||
| 		pd->dma_rx = NULL; | ||||
| 		pd->dma_rx = ERR_PTR(-EPROBE_DEFER); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| @ -849,6 +855,7 @@ static int sh_mobile_i2c_probe(struct platform_device *dev) | ||||
| 
 | ||||
| 	res = platform_get_resource(dev, IORESOURCE_MEM, 0); | ||||
| 
 | ||||
| 	pd->res = res; | ||||
| 	pd->reg = devm_ioremap_resource(&dev->dev, res); | ||||
| 	if (IS_ERR(pd->reg)) | ||||
| 		return PTR_ERR(pd->reg); | ||||
| @ -889,17 +896,7 @@ static int sh_mobile_i2c_probe(struct platform_device *dev) | ||||
| 	/* Init DMA */ | ||||
| 	sg_init_table(&pd->sg, 1); | ||||
| 	pd->dma_direction = DMA_NONE; | ||||
| 	ret = sh_mobile_i2c_request_dma_chan(pd->dev, DMA_DEV_TO_MEM, | ||||
| 					     res->start + ICDR, &pd->dma_rx); | ||||
| 	if (ret == -EPROBE_DEFER) | ||||
| 		return ret; | ||||
| 
 | ||||
| 	ret = sh_mobile_i2c_request_dma_chan(pd->dev, DMA_MEM_TO_DEV, | ||||
| 					     res->start + ICDR, &pd->dma_tx); | ||||
| 	if (ret == -EPROBE_DEFER) { | ||||
| 		sh_mobile_i2c_release_dma(pd); | ||||
| 		return ret; | ||||
| 	} | ||||
| 	pd->dma_rx = pd->dma_tx = ERR_PTR(-EPROBE_DEFER); | ||||
| 
 | ||||
| 	/* Enable Runtime PM for this device.
 | ||||
| 	 * | ||||
| @ -937,8 +934,7 @@ static int sh_mobile_i2c_probe(struct platform_device *dev) | ||||
| 		return ret; | ||||
| 	} | ||||
| 
 | ||||
| 	dev_info(&dev->dev, "I2C adapter %d, bus speed %lu Hz, DMA=%c\n", | ||||
| 		 adap->nr, pd->bus_speed, (pd->dma_rx || pd->dma_tx) ? 'y' : 'n'); | ||||
| 	dev_info(&dev->dev, "I2C adapter %d, bus speed %lu Hz\n", adap->nr, pd->bus_speed); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| @ -204,16 +204,6 @@ config THERM_ADT746X | ||||
|           iBook G4, and the ATI based aluminium PowerBooks, allowing slightly | ||||
| 	  better fan behaviour by default, and some manual control. | ||||
| 
 | ||||
| config THERM_PM72 | ||||
| 	tristate "Support for thermal management on PowerMac G5 (AGP)" | ||||
| 	depends on I2C && I2C_POWERMAC && PPC_PMAC64 | ||||
| 	default n | ||||
| 	help | ||||
| 	  This driver provides thermostat and fan control for the desktop | ||||
| 	  G5 machines. | ||||
| 
 | ||||
| 	  This is deprecated, use windfarm instead. | ||||
| 
 | ||||
| config WINDFARM | ||||
| 	tristate "New PowerMac thermal control infrastructure" | ||||
| 	depends on PPC | ||||
|  | ||||
| @ -25,7 +25,6 @@ obj-$(CONFIG_ADB_IOP)		+= adb-iop.o | ||||
| obj-$(CONFIG_ADB_PMU68K)	+= via-pmu68k.o | ||||
| obj-$(CONFIG_ADB_MACIO)		+= macio-adb.o | ||||
| 
 | ||||
| obj-$(CONFIG_THERM_PM72)	+= therm_pm72.o | ||||
| obj-$(CONFIG_THERM_WINDTUNNEL)	+= therm_windtunnel.o | ||||
| obj-$(CONFIG_THERM_ADT746X)	+= therm_adt746x.o | ||||
| obj-$(CONFIG_WINDFARM)	        += windfarm_core.o | ||||
|  | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -1,326 +0,0 @@ | ||||
| #ifndef __THERM_PMAC_7_2_H__ | ||||
| #define __THERM_PMAC_7_2_H__ | ||||
| 
 | ||||
| typedef unsigned short fu16; | ||||
| typedef int fs32; | ||||
| typedef short fs16; | ||||
| 
 | ||||
| struct mpu_data | ||||
| { | ||||
| 	u8	signature;		/* 0x00 - EEPROM sig. */ | ||||
| 	u8	bytes_used;		/* 0x01 - Bytes used in eeprom (160 ?) */ | ||||
| 	u8	size;			/* 0x02 - EEPROM size (256 ?) */ | ||||
| 	u8	version;		/* 0x03 - EEPROM version */ | ||||
| 	u32	data_revision;		/* 0x04 - Dataset revision */ | ||||
| 	u8	processor_bin_code[3];	/* 0x08 - Processor BIN code */ | ||||
| 	u8	bin_code_expansion;	/* 0x0b - ??? (padding ?) */ | ||||
| 	u8	processor_num;		/* 0x0c - Number of CPUs on this MPU */ | ||||
| 	u8	input_mul_bus_div;	/* 0x0d - Clock input multiplier/bus divider */ | ||||
| 	u8	reserved1[2];		/* 0x0e - */ | ||||
| 	u32	input_clk_freq_high;	/* 0x10 - Input clock frequency high */ | ||||
| 	u8	cpu_nb_target_cycles;	/* 0x14 - ??? */ | ||||
| 	u8	cpu_statlat;		/* 0x15 - ??? */ | ||||
| 	u8	cpu_snooplat;		/* 0x16 - ??? */ | ||||
| 	u8	cpu_snoopacc;		/* 0x17 - ??? */ | ||||
| 	u8	nb_paamwin;		/* 0x18 - ??? */ | ||||
| 	u8	nb_statlat;		/* 0x19 - ??? */ | ||||
| 	u8	nb_snooplat;		/* 0x1a - ??? */ | ||||
| 	u8	nb_snoopwin;		/* 0x1b - ??? */ | ||||
| 	u8	api_bus_mode;		/* 0x1c - ??? */ | ||||
| 	u8	reserved2[3];		/* 0x1d - */ | ||||
| 	u32	input_clk_freq_low;	/* 0x20 - Input clock frequency low */ | ||||
| 	u8	processor_card_slot;	/* 0x24 - Processor card slot number */ | ||||
| 	u8	reserved3[2];		/* 0x25 - */ | ||||
| 	u8	padjmax;       		/* 0x27 - Max power adjustment (Not in OF!) */ | ||||
| 	u8	ttarget;		/* 0x28 - Target temperature */ | ||||
| 	u8	tmax;			/* 0x29 - Max temperature */ | ||||
| 	u8	pmaxh;			/* 0x2a - Max power */ | ||||
| 	u8	tguardband;		/* 0x2b - Guardband temp ??? Hist. len in OSX */ | ||||
| 	fs32	pid_gp;			/* 0x2c - PID proportional gain */ | ||||
| 	fs32	pid_gr;			/* 0x30 - PID reset gain */ | ||||
| 	fs32	pid_gd;			/* 0x34 - PID derivative gain */ | ||||
| 	fu16	voph;			/* 0x38 - Vop High */ | ||||
| 	fu16	vopl;			/* 0x3a - Vop Low */ | ||||
| 	fs16	nactual_die;		/* 0x3c - nActual Die */ | ||||
| 	fs16	nactual_heatsink;	/* 0x3e - nActual Heatsink */ | ||||
| 	fs16	nactual_system;		/* 0x40 - nActual System */ | ||||
| 	u16	calibration_flags;	/* 0x42 - Calibration flags */ | ||||
| 	fu16	mdiode;			/* 0x44 - Diode M value (scaling factor) */ | ||||
| 	fs16	bdiode;			/* 0x46 - Diode B value (offset) */ | ||||
| 	fs32	theta_heat_sink;	/* 0x48 - Theta heat sink */ | ||||
| 	u16	rminn_intake_fan;	/* 0x4c - Intake fan min RPM */ | ||||
| 	u16	rmaxn_intake_fan;	/* 0x4e - Intake fan max RPM */ | ||||
| 	u16	rminn_exhaust_fan;	/* 0x50 - Exhaust fan min RPM */ | ||||
| 	u16	rmaxn_exhaust_fan;	/* 0x52 - Exhaust fan max RPM */ | ||||
| 	u8	processor_part_num[8];	/* 0x54 - Processor part number XX pumps min/max */ | ||||
| 	u32	processor_lot_num;	/* 0x5c - Processor lot number */ | ||||
| 	u8	orig_card_sernum[0x10];	/* 0x60 - Card original serial number */ | ||||
| 	u8	curr_card_sernum[0x10];	/* 0x70 - Card current serial number */ | ||||
| 	u8	mlb_sernum[0x18];	/* 0x80 - MLB serial number */ | ||||
| 	u32	checksum1;		/* 0x98 - */ | ||||
| 	u32	checksum2;		/* 0x9c - */	 | ||||
| }; /* Total size = 0xa0 */ | ||||
| 
 | ||||
| /* Display a 16.16 fixed point value */ | ||||
| #define FIX32TOPRINT(f)	((f) >> 16),((((f) & 0xffff) * 1000) >> 16) | ||||
| 
 | ||||
| /*
 | ||||
|  * Maximum number of seconds to be in critical state (after a | ||||
|  * normal shutdown attempt). If the machine isn't down after | ||||
|  * this counter elapses, we force an immediate machine power | ||||
|  * off. | ||||
|  */ | ||||
| #define MAX_CRITICAL_STATE			30 | ||||
| static char * critical_overtemp_path = "/sbin/critical_overtemp"; | ||||
| 
 | ||||
| /*
 | ||||
|  * This option is "weird" :) Basically, if you define this to 1 | ||||
|  * the control loop for the RPMs fans (not PWMs) will apply the | ||||
|  * correction factor obtained from the PID to the _actual_ RPM | ||||
|  * speed read from the FCU. | ||||
|  * If you define the below constant to 0, then it will be | ||||
|  * applied to the setpoint RPM speed, that is basically the | ||||
|  * speed we proviously "asked" for. | ||||
|  * | ||||
|  * I'm not sure which of these Apple's algorithm is supposed | ||||
|  * to use | ||||
|  */ | ||||
| #define RPM_PID_USE_ACTUAL_SPEED		0 | ||||
| 
 | ||||
| /*
 | ||||
|  * i2c IDs. Currently, we hard code those and assume that | ||||
|  * the FCU is on U3 bus 1 while all sensors are on U3 bus | ||||
|  * 0. This appear to be safe enough for this first version | ||||
|  * of the driver, though I would accept any clean patch | ||||
|  * doing a better use of the device-tree without turning the | ||||
|  * while i2c registration mechanism into a racy mess | ||||
|  * | ||||
|  * Note: Xserve changed this. We have some bits on the K2 bus, | ||||
|  * which I arbitrarily set to 0x200. Ultimately, we really want | ||||
|  * too lookup these in the device-tree though | ||||
|  */ | ||||
| #define FAN_CTRLER_ID		0x15e | ||||
| #define SUPPLY_MONITOR_ID      	0x58 | ||||
| #define SUPPLY_MONITORB_ID     	0x5a | ||||
| #define DRIVES_DALLAS_ID	0x94 | ||||
| #define BACKSIDE_MAX_ID		0x98 | ||||
| #define XSERVE_DIMMS_LM87	0x25a | ||||
| #define XSERVE_SLOTS_LM75	0x290 | ||||
| 
 | ||||
| /*
 | ||||
|  * Some MAX6690, DS1775, LM87 register definitions | ||||
|  */ | ||||
| #define MAX6690_INT_TEMP	0 | ||||
| #define MAX6690_EXT_TEMP	1 | ||||
| #define DS1775_TEMP		0 | ||||
| #define LM87_INT_TEMP		0x27 | ||||
| 
 | ||||
| /*
 | ||||
|  * Scaling factors for the AD7417 ADC converters (except | ||||
|  * for the CPU diode which is obtained from the EEPROM). | ||||
|  * Those values are obtained from the property list of | ||||
|  * the darwin driver | ||||
|  */ | ||||
| #define ADC_12V_CURRENT_SCALE	0x0320	/* _AD2 */ | ||||
| #define ADC_CPU_VOLTAGE_SCALE	0x00a0	/* _AD3 */ | ||||
| #define ADC_CPU_CURRENT_SCALE	0x1f40	/* _AD4 */ | ||||
| 
 | ||||
| /*
 | ||||
|  * PID factors for the U3/Backside fan control loop. We have 2 sets | ||||
|  * of values here, one set for U3 and one set for U3H | ||||
|  */ | ||||
| #define BACKSIDE_FAN_PWM_DEFAULT_ID	1 | ||||
| #define BACKSIDE_FAN_PWM_INDEX		0 | ||||
| #define BACKSIDE_PID_U3_G_d		0x02800000 | ||||
| #define BACKSIDE_PID_U3H_G_d		0x01400000 | ||||
| #define BACKSIDE_PID_RACK_G_d		0x00500000 | ||||
| #define BACKSIDE_PID_G_p		0x00500000 | ||||
| #define BACKSIDE_PID_RACK_G_p		0x0004cccc | ||||
| #define BACKSIDE_PID_G_r		0x00000000 | ||||
| #define BACKSIDE_PID_U3_INPUT_TARGET	0x00410000 | ||||
| #define BACKSIDE_PID_U3H_INPUT_TARGET	0x004b0000 | ||||
| #define BACKSIDE_PID_RACK_INPUT_TARGET	0x00460000 | ||||
| #define BACKSIDE_PID_INTERVAL		5 | ||||
| #define BACKSIDE_PID_RACK_INTERVAL	1 | ||||
| #define BACKSIDE_PID_OUTPUT_MAX		100 | ||||
| #define BACKSIDE_PID_U3_OUTPUT_MIN	20 | ||||
| #define BACKSIDE_PID_U3H_OUTPUT_MIN	20 | ||||
| #define BACKSIDE_PID_HISTORY_SIZE	2 | ||||
| 
 | ||||
| struct basckside_pid_params | ||||
| { | ||||
| 	s32			G_d; | ||||
| 	s32			G_p; | ||||
| 	s32			G_r; | ||||
| 	s32			input_target; | ||||
| 	s32			output_min; | ||||
| 	s32			output_max; | ||||
| 	s32			interval; | ||||
| 	int			additive; | ||||
| }; | ||||
| 
 | ||||
| struct backside_pid_state | ||||
| { | ||||
| 	int			ticks; | ||||
| 	struct i2c_client *	monitor; | ||||
| 	s32		       	sample_history[BACKSIDE_PID_HISTORY_SIZE]; | ||||
| 	s32			error_history[BACKSIDE_PID_HISTORY_SIZE]; | ||||
| 	int			cur_sample; | ||||
| 	s32			last_temp; | ||||
| 	int			pwm; | ||||
| 	int			first; | ||||
| }; | ||||
| 
 | ||||
| /*
 | ||||
|  * PID factors for the Drive Bay fan control loop | ||||
|  */ | ||||
| #define DRIVES_FAN_RPM_DEFAULT_ID	2 | ||||
| #define DRIVES_FAN_RPM_INDEX		1 | ||||
| #define DRIVES_PID_G_d			0x01e00000 | ||||
| #define DRIVES_PID_G_p			0x00500000 | ||||
| #define DRIVES_PID_G_r			0x00000000 | ||||
| #define DRIVES_PID_INPUT_TARGET		0x00280000 | ||||
| #define DRIVES_PID_INTERVAL    		5 | ||||
| #define DRIVES_PID_OUTPUT_MAX		4000 | ||||
| #define DRIVES_PID_OUTPUT_MIN		300 | ||||
| #define DRIVES_PID_HISTORY_SIZE		2 | ||||
| 
 | ||||
| struct drives_pid_state | ||||
| { | ||||
| 	int			ticks; | ||||
| 	struct i2c_client *	monitor; | ||||
| 	s32	       		sample_history[BACKSIDE_PID_HISTORY_SIZE]; | ||||
| 	s32			error_history[BACKSIDE_PID_HISTORY_SIZE]; | ||||
| 	int			cur_sample; | ||||
| 	s32			last_temp; | ||||
| 	int			rpm; | ||||
| 	int			first; | ||||
| }; | ||||
| 
 | ||||
| #define SLOTS_FAN_PWM_DEFAULT_ID	2 | ||||
| #define SLOTS_FAN_PWM_INDEX		2 | ||||
| #define	SLOTS_FAN_DEFAULT_PWM		40 /* Do better here ! */ | ||||
| 
 | ||||
| 
 | ||||
| /*
 | ||||
|  * PID factors for the Xserve DIMM control loop | ||||
|  */ | ||||
| #define DIMM_PID_G_d			0 | ||||
| #define DIMM_PID_G_p			0 | ||||
| #define DIMM_PID_G_r			0x06553600 | ||||
| #define DIMM_PID_INPUT_TARGET		3276800 | ||||
| #define DIMM_PID_INTERVAL    		1 | ||||
| #define DIMM_PID_OUTPUT_MAX		14000 | ||||
| #define DIMM_PID_OUTPUT_MIN		4000 | ||||
| #define DIMM_PID_HISTORY_SIZE		20 | ||||
| 
 | ||||
| struct dimm_pid_state | ||||
| { | ||||
| 	int			ticks; | ||||
| 	struct i2c_client *	monitor; | ||||
| 	s32	       		sample_history[DIMM_PID_HISTORY_SIZE]; | ||||
| 	s32			error_history[DIMM_PID_HISTORY_SIZE]; | ||||
| 	int			cur_sample; | ||||
| 	s32			last_temp; | ||||
| 	int			first; | ||||
| 	int			output; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| /*
 | ||||
|  * PID factors for the Xserve Slots control loop | ||||
|  */ | ||||
| #define SLOTS_PID_G_d			0 | ||||
| #define SLOTS_PID_G_p			0 | ||||
| #define SLOTS_PID_G_r			0x00100000 | ||||
| #define SLOTS_PID_INPUT_TARGET		3200000 | ||||
| #define SLOTS_PID_INTERVAL    		1 | ||||
| #define SLOTS_PID_OUTPUT_MAX		100 | ||||
| #define SLOTS_PID_OUTPUT_MIN		20 | ||||
| #define SLOTS_PID_HISTORY_SIZE		20 | ||||
| 
 | ||||
| struct slots_pid_state | ||||
| { | ||||
| 	int			ticks; | ||||
| 	struct i2c_client *	monitor; | ||||
| 	s32	       		sample_history[SLOTS_PID_HISTORY_SIZE]; | ||||
| 	s32			error_history[SLOTS_PID_HISTORY_SIZE]; | ||||
| 	int			cur_sample; | ||||
| 	s32			last_temp; | ||||
| 	int			first; | ||||
| 	int			pwm; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /* Desktops */ | ||||
| 
 | ||||
| #define CPUA_INTAKE_FAN_RPM_DEFAULT_ID	3 | ||||
| #define CPUA_EXHAUST_FAN_RPM_DEFAULT_ID	4 | ||||
| #define CPUB_INTAKE_FAN_RPM_DEFAULT_ID	5 | ||||
| #define CPUB_EXHAUST_FAN_RPM_DEFAULT_ID	6 | ||||
| 
 | ||||
| #define CPUA_INTAKE_FAN_RPM_INDEX	3 | ||||
| #define CPUA_EXHAUST_FAN_RPM_INDEX	4 | ||||
| #define CPUB_INTAKE_FAN_RPM_INDEX	5 | ||||
| #define CPUB_EXHAUST_FAN_RPM_INDEX	6 | ||||
| 
 | ||||
| #define CPU_INTAKE_SCALE		0x0000f852 | ||||
| #define CPU_TEMP_HISTORY_SIZE		2 | ||||
| #define CPU_POWER_HISTORY_SIZE		10 | ||||
| #define CPU_PID_INTERVAL		1 | ||||
| #define CPU_MAX_OVERTEMP		90 | ||||
| 
 | ||||
| #define CPUA_PUMP_RPM_INDEX		7 | ||||
| #define CPUB_PUMP_RPM_INDEX		8 | ||||
| #define CPU_PUMP_OUTPUT_MAX		3200 | ||||
| #define CPU_PUMP_OUTPUT_MIN		1250 | ||||
| 
 | ||||
| /* Xserve */ | ||||
| #define CPU_A1_FAN_RPM_INDEX		9 | ||||
| #define CPU_A2_FAN_RPM_INDEX		10 | ||||
| #define CPU_A3_FAN_RPM_INDEX		11 | ||||
| #define CPU_B1_FAN_RPM_INDEX		12 | ||||
| #define CPU_B2_FAN_RPM_INDEX		13 | ||||
| #define CPU_B3_FAN_RPM_INDEX		14 | ||||
| 
 | ||||
| 
 | ||||
| struct cpu_pid_state | ||||
| { | ||||
| 	int			index; | ||||
| 	struct i2c_client *	monitor; | ||||
| 	struct mpu_data		mpu; | ||||
| 	int			overtemp; | ||||
| 	s32	       		temp_history[CPU_TEMP_HISTORY_SIZE]; | ||||
| 	int			cur_temp; | ||||
| 	s32			power_history[CPU_POWER_HISTORY_SIZE]; | ||||
| 	s32			error_history[CPU_POWER_HISTORY_SIZE]; | ||||
| 	int			cur_power; | ||||
| 	int			count_power; | ||||
| 	int			rpm; | ||||
| 	int			intake_rpm; | ||||
| 	s32			voltage; | ||||
| 	s32			current_a; | ||||
| 	s32			last_temp; | ||||
| 	s32			last_power; | ||||
| 	int			first; | ||||
| 	u8			adc_config; | ||||
| 	s32			pump_min; | ||||
| 	s32			pump_max; | ||||
| }; | ||||
| 
 | ||||
| /* Tickle FCU every 10 seconds */ | ||||
| #define FCU_TICKLE_TICKS	10 | ||||
| 
 | ||||
| /*
 | ||||
|  * Driver state | ||||
|  */ | ||||
| enum { | ||||
| 	state_detached, | ||||
| 	state_attaching, | ||||
| 	state_attached, | ||||
| 	state_detaching, | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| #endif /* __THERM_PMAC_7_2_H__ */ | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user