From: Ben Dooks <ben-linux-elnMNo+KYs3YtjvyW6yDsg@public.gmane.org>
To: Alan Cox <alan-qBU/x9rampVanCEyBjwyrvXRex20P6io@public.gmane.org>
Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
khali-PUYAD+kWke1g9hUCZPvPmw@public.gmane.org
Subject: Re: [PATCH] I2C driver supporting Moorestown and Medfield platform
Date: Tue, 26 Oct 2010 23:54:12 +0100 [thread overview]
Message-ID: <4CC75C14.3000101@fluff.org> (raw)
In-Reply-To: <20101022140431.3545.37799.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
On 22/10/10 15:05, Alan Cox wrote:
> I think this now addresses all the points raised in previous review, as well
I'll go through and have a quick look through this to
see if there is anything else to look at.
> +/* Tables use: 0 Moorestown, 1 Medfield */
> +#define NUM_PLATFORMS 2
> +enum platform_enum {
> + MOORESTOWN = 0,
> + MEDFIELD = 1,
> +};
> +
> +struct intel_mid_i2c_private {
> + struct i2c_adapter adap;
> + /* Device for power management */
> + struct device *dev;
> + /* Register base address */
> + void __iomem *base;
> + /* Speed mode */
> + int speed;
> + /* Transaction completion wait */
> + struct completion complete;
> + /* Saved abort reason */
> + int abort;
> + /* Working buffer */
> + u8 *rx_buf;
> + int rx_buf_len;
> + /* Adapter state machine condition */
> + int status;
> + /* Message being processed */
> + struct i2c_msg *msg;
> + /* Which Intel MID device are we today */
> + enum platform_enum platform;
> + /* Serialize transactions */
> + struct mutex lock;
> +};
would have prefered this as kerneldoc.
> +
> +#define NUM_SPEEDS 3
> +
> +#define ACTIVE 0
> +#define STANDBY 1
> +
> +#define STATUS_IDLE 0
> +#define STATUS_READ_START 1
> +#define STATUS_READ_IN_PROGRESS 2
> +#define STATUS_READ_SUCCESS 3
> +#define STATUS_WRITE_START 4
> +#define STATUS_WRITE_SUCCESS 5
> +#define STATUS_XFER_ABORT 6
> +#define STATUS_STANDBY 7
would have been nicer as an enum.
> +/**
> + * intel_mid_i2c_disable - Disable I2C controller
> + * @adap: struct pointer to i2c_adapter
> + *
> + * Return Value:
> + * 0 success
> + * -EBUSY if device is busy
> + * -ETIMEDOUT if i2c cannot be disabled within the given time
> + *
> + * I2C bus state should be checked prior to disabling the hardware. If bus is
> + * not in idle state, an errno is returned. Write "0" to IC_ENABLE to disable
> + * I2C controller.
> + */
> +static int intel_mid_i2c_disable(struct i2c_adapter *adap)
> +{
> + struct intel_mid_i2c_private *i2c = i2c_get_adapdata(adap);
> + int err = 0;
> + int count = 0;
> + int ret1, ret2;
> + static const u16 delay[NUM_SPEEDS] = {100, 25, 3};
> +
> + /* Set IC_ENABLE to 0 */
> + writel(0, i2c->base + IC_ENABLE);
> +
> + /* Check if device is busy */
> + dev_dbg(&adap->dev, "mrst i2c disable\n");
> + while ((ret1 = readl(i2c->base + IC_ENABLE_STATUS) & 0x1)
> + || (ret2 = readl(i2c->base + IC_STATUS) & 0x1)) {
> + udelay(delay[i2c->speed]);
> + writel(0, i2c->base + IC_ENABLE);
> + dev_dbg(&adap->dev, "i2c is busy, count is %d speed %d\n",
> + count, i2c->speed);
> + if (count++ > 10) {
> + err = -ETIMEDOUT;
> + break;
> + }
> + }
> +
> + /* Clear all interrupts */
> + readl(i2c->base + IC_CLR_INTR);
> + readl(i2c->base + IC_CLR_STOP_DET);
> + readl(i2c->base + IC_CLR_START_DET);
> + readl(i2c->base + IC_CLR_ACTIVITY);
> + readl(i2c->base + IC_CLR_TX_ABRT);
> + readl(i2c->base + IC_CLR_RX_OVER);
> + readl(i2c->base + IC_CLR_RX_UNDER);
> + readl(i2c->base + IC_CLR_TX_OVER);
> + readl(i2c->base + IC_CLR_RX_DONE);
> + readl(i2c->base + IC_CLR_GEN_CALL);
> +
> + /* Disable all interupts */
> + writel(0x0000, i2c->base + IC_INTR_MASK);
> +
> + return err;
> +}
> +
> +/**
> + * intel_mid_i2c_hwinit - Initialize the I2C hardware registers
> + * @dev: pci device struct pointer
> + *
> + * This function will be called in intel_mid_i2c_probe() before device
> + * registration.
> + *
> + * Return Values:
> + * 0 success
> + * -EBUSY i2c cannot be disabled
> + * -ETIMEDOUT i2c cannot be disabled
> + * -EFAULT If APB data width is not 32-bit wide
> + *
> + * I2C should be disabled prior to other register operation. If failed, an
> + * errno is returned. Mask and Clear all interrpts, this should be done at
> + * first. Set common registers which will not be modified during normal
> + * transfers, including: controll register, FIFO threshold and clock freq.
> + * Check APB data width at last.
> + */
> +static int intel_mid_i2c_hwinit(struct intel_mid_i2c_private *i2c)
> +{
> + int err;
> +
> + static const u16 hcnt[NUM_PLATFORMS][NUM_SPEEDS] = {
> + { 0x75, 0x15, 0x07 },
> + { 0x04c, 0x10, 0x06 }
> + };
> + static const u16 lcnt[NUM_PLATFORMS][NUM_SPEEDS] = {
> + { 0x7C, 0x21, 0x0E },
> + { 0x053, 0x19, 0x0F }
> + };
> +
> + /* Disable i2c first */
> + err = intel_mid_i2c_disable(&i2c->adap);
> + if (err)
> + return err;
> +
> + /*
> + * Setup clock frequency and speed mode
> + * Enable restart condition,
> + * enable master FSM, disable slave FSM,
> + * use target address when initiating transfer
> + */
> +
> + writel((i2c->speed + 1) << 1 | SLV_DIS | RESTART | MASTER_EN,
> + i2c->base + IC_CON);
> + writel(hcnt[i2c->platform][i2c->speed],
> + i2c->base + (IC_SS_SCL_HCNT + (i2c->speed << 3)));
> + writel(lcnt[i2c->platform][i2c->speed],
> + i2c->base + (IC_SS_SCL_LCNT + (i2c->speed << 3)));
> +
> + /* Set tranmit & receive FIFO threshold to zero */
> + writel(0x0, i2c->base + IC_RX_TL);
> + writel(0x0, i2c->base + IC_TX_TL);
> +
> + return 0;
> +}
> +
> +/**
> + * intel_mid_i2c_func - Return the supported three I2C operations.
> + * @adapter: i2c_adapter struct pointer
> + */
> +static u32 intel_mid_i2c_func(struct i2c_adapter *adapter)
> +{
> + return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR | I2C_FUNC_SMBUS_EMUL;
> +}
> +
> +/**
> + * intel_mid_i2c_address_neq - To check if the addresses for different i2c messages
> + * are equal.
> + * @p1: first i2c_msg
> + * @p2: second i2c_msg
> + *
> + * Return Values:
> + * 0 if addresses are equal
> + * 1 if not equal
> + *
> + * Within a single transfer, the I2C client may need to send its address more
> + * than once. So a check if the addresses match is needed.
> + */
> +static inline bool intel_mid_i2c_address_neq(const struct i2c_msg *p1,
> + const struct i2c_msg *p2)
> +{
> + if (p1->addr != p2->addr)
> + return 1;
> + if ((p1->flags ^ p2->flags) & I2C_M_TEN)
> + return 1;
> + return 0;
> +}
> +
> +/**
> + * intel_mid_i2c_abort - To handle transfer abortions and print error messages.
> + * @adap: i2c_adapter struct pointer
> + *
> + * By reading register IC_TX_ABRT_SOURCE, various transfer errors can be
> + * distingushed. At present, no circumstances have been found out that
> + * multiple errors would be occured simutaneously, so we simply use the
> + * register value directly.
> + *
> + * At last the error bits are cleared. (Note clear ABRT_SBYTE_NORSTRT bit need
> + * a few extra steps)
> + */
> +static void intel_mid_i2c_abort(struct intel_mid_i2c_private *i2c)
> +{
> + /* Read about source register */
> + int abort = i2c->abort;
> + struct i2c_adapter *adap = &i2c->adap;
> +
> + /* Single transfer error check:
> + * According to databook, TX/RX FIFOs would be flushed when
> + * the abort interrupt occured.
> + */
> + if (abort & ABRT_MASTER_DIS)
> + dev_err(&adap->dev,
> + "initiate master operation with master mode disabled.\n");
> + if (abort & ABRT_10B_RD_NORSTRT)
> + dev_err(&adap->dev,
> + "RESTART disabled and master sent READ cmd in 10-bit addressing.\n");
> +
> + if (abort & ABRT_SBYTE_NORSTRT) {
> + dev_err(&adap->dev,
> + "RESTART disabled and user is trying to send START byte.\n");
> + writel(~ABRT_SBYTE_NORSTRT, i2c->base + IC_TX_ABRT_SOURCE);
> + writel(RESTART, i2c->base + IC_CON);
> + writel(~IC_TAR_SPECIAL, i2c->base + IC_TAR);
> + }
> +
> + if (abort & ABRT_SBYTE_ACKDET)
> + dev_err(&adap->dev,
> + "START byte was acknowledged.\n");
surely the start+addr byte has to be acked?
> + if (abort & ABRT_TXDATA_NOACK)
> + dev_err(&adap->dev,
> + "No acknowledgement received from slave.\n");
you'll get a pile of errors if the eeprom driver uses this method
to test for eeprom busy. you may want to push this one back to dev_dbg.
> + if (abort & ABRT_10ADDR2_NOACK)
> + dev_dbg(&adap->dev,
> + "The 2nd address byte of the 10-bit address was not acknowledged.\n");
> + if (abort & ABRT_10ADDR1_NOACK)
> + dev_dbg(&adap->dev,
> + "The 1st address byte of 10-bit address was not acknowledged.\n");
> + if (abort & ABRT_7B_ADDR_NOACK)
> + dev_dbg(&adap->dev,
> + "I2C slave device not acknowledged.\n");
> + /* Clear TX_ABRT bit */
> + readl(i2c->base + IC_CLR_TX_ABRT);
> + i2c->status = STATUS_XFER_ABORT;
> +}
> +
> +/**
> + * xfer_read - Internal function to implement master read transfer.
> + * @adap: i2c_adapter struct pointer
> + * @buf: buffer in i2c_msg
> + * @length: number of bytes to be read
> + *
> + * Return Values:
> + * 0 if the read transfer succeeds
> + * -ETIMEDOUT if cannot read the "raw" interrupt register
> + * -EINVAL if a transfer abort occurred
> + *
> + * For every byte, a "READ" command will be loaded into IC_DATA_CMD prior to
> + * data transfer. The actual "read" operation will be performed if an RX_FULL
> + * interrupt occurred.
> + *
> + * Note there may be two interrupt signals captured, one should read
> + * IC_RAW_INTR_STAT to separate between errors and actual data.
> + */
> +static int xfer_read(struct i2c_adapter *adap, unsigned char *buf, int length)
> +{
> + struct intel_mid_i2c_private *i2c = i2c_get_adapdata(adap);
> + int i = length;
> + int err;
> +
> + if (length >= 256) {
> + dev_err(&adap->dev,
> + "I2C FIFO cannot support larger than 256 bytes\n");
> + return -EMSGSIZE;
> + }
> +
> + INIT_COMPLETION(i2c->complete);
> +
> + readl(i2c->base + IC_CLR_INTR);
> + writel(0x0044, i2c->base + IC_INTR_MASK);
> +
> + i2c->status = STATUS_READ_START;
> +
> + while (i--)
> + writel(IC_RD, i2c->base + IC_DATA_CMD);
> +
> + i2c->status = STATUS_READ_START;
> + err = wait_for_completion_interruptible_timeout(&i2c->complete, HZ);
> + if (!err) {
> + dev_err(&adap->dev, "Timeout for ACK from I2C slave device\n");
> + intel_mid_i2c_hwinit(i2c);
> + return -ETIMEDOUT;
> + } else {
as a note, you really didn't need the else here, you exit with the
return at the end of the block.
> + if (i2c->status == STATUS_READ_SUCCESS)
> + return 0;
> + else
> + return -EIO;
> + }
> +}
> +static int intel_mid_i2c_setup(struct i2c_adapter *adap, struct i2c_msg *pmsg)
> +{
> + struct intel_mid_i2c_private *i2c = i2c_get_adapdata(adap);
> + int err;
> + u32 reg;
> + u32 bit_mask;
> + u32 mode;
> +
> + /* Disable device first */
> + err = intel_mid_i2c_disable(adap);
> + if (err) {
> + dev_err(&adap->dev,
> + "Cannot disable i2c controller, timeout\n");
> + return err;
> + }
> +
> + mode = (1 + i2c->speed) << 1;
> + /* set the speed mode */
> + reg = readl(i2c->base + IC_CON);
> + if ((reg & 0x06) != mode) {
> + dev_dbg(&adap->dev, "set mode %d\n", i2c->speed);
> + writel((reg & ~0x6) | mode, i2c->base + IC_CON);
> + }
> +
> + reg = readl(i2c->base + IC_CON);
> + /* use 7-bit addressing */
> + if (pmsg->flags & I2C_M_TEN) {
> + if ((reg & ADDR_10BIT) != ADDR_10BIT) {
> + dev_dbg(&adap->dev, "set i2c 10 bit address mode\n");
> + writel(reg | ADDR_10BIT, i2c->base + IC_CON);
> + }
> + } else {
> + if ((reg & ADDR_10BIT) != 0x0) {
> + dev_dbg(&adap->dev, "set i2c 7 bit address mode\n");
> + writel(reg & ~ADDR_10BIT, i2c->base + IC_CON);
> + }
> + }
> + /* enable restart conditions */
> + reg = readl(i2c->base + IC_CON);
> + if ((reg & RESTART) != RESTART) {
> + dev_dbg(&adap->dev, "enable restart conditions\n");
> + writel(reg | RESTART, i2c->base + IC_CON);
> + }
> +
> + /* enable master FSM */
> + reg = readl(i2c->base + IC_CON);
> + dev_dbg(&adap->dev, "ic_con reg is 0x%x\n", reg);
> + writel(reg | MASTER_EN, i2c->base + IC_CON);
> + if ((reg & SLV_DIS) != SLV_DIS) {
> + dev_dbg(&adap->dev, "enable master FSM\n");
> + writel(reg | SLV_DIS, i2c->base + IC_CON);
> + dev_dbg(&adap->dev, "ic_con reg is 0x%x\n", reg);
> + }
> +
> + /* use target address when initiating transfer */
> + reg = readl(i2c->base + IC_TAR);
> + bit_mask = IC_TAR_SPECIAL | IC_TAR_GC_OR_START;
> +
> + if ((reg & bit_mask) != 0x0) {
> + dev_dbg(&adap->dev,
> + "WR: use target address when intiating transfer, i2c_tx_target\n");
> + writel(reg & ~bit_mask, i2c->base + IC_TAR);
> + }
> +
> + /* set target address to the I2C slave address */
> + dev_dbg(&adap->dev,
> + "set target address to the I2C slave address, addr is %x\n",
> + pmsg->addr);
> + writel(pmsg->addr | (pmsg->flags & I2C_M_TEN ? IC_TAR_10BIT_ADDR : 0),
> + i2c->base + IC_TAR);
> +
> + /* Enable I2C controller */
> + writel(ENABLE, i2c->base + IC_ENABLE);
> +
> + return 0;
> +}
> +
> +/**
> + * intel_mid_i2c_xfer - Main master transfer routine.
> + * @adap: i2c_adapter struct pointer
> + * @pmsg: i2c_msg struct pointer
> + * @num: number of i2c_msg
> + *
> + * Return Values:
> + * + number of messages transfered
> + * -ETIMEDOUT If cannot disable I2C controller or read IC_STATUS
> + * -EINVAL If the address in i2c_msg is invalid
> + *
> + * This function will be registered in i2c-core and exposed to external
> + * I2C clients.
> + * 1. Disable I2C controller
> + * 2. Unmask three interrupts: RX_FULL, TX_EMPTY, TX_ABRT
> + * 3. Check if address in i2c_msg is valid
> + * 4. Enable I2C controller
> + * 5. Perform real transfer (call xfer_read or xfer_write)
> + * 6. Wait until the current transfer is finished (check bus state)
> + * 7. Mask and clear all interrupts
> + */
> +static int intel_mid_i2c_xfer(struct i2c_adapter *adap,
> + struct i2c_msg *pmsg,
> + int num)
> +{
> + struct intel_mid_i2c_private *i2c = i2c_get_adapdata(adap);
> + int i, err;
> +
> + pm_runtime_get(i2c->dev);
> +
> + mutex_lock(&i2c->lock);
> + dev_dbg(&adap->dev, "intel_mid_i2c_xfer, process %d msg(s)\n", num);
> + dev_dbg(&adap->dev, "slave address is %x\n", pmsg->addr);
> +
> + if (i2c->status != STATUS_IDLE) {
> + dev_err(&adap->dev, "Adapter %d in transfer/standby\n",
> + adap->nr);
> + mutex_unlock(&i2c->lock);
> + pm_runtime_put(i2c->dev);
> + return -1;
> + }
> +
> + /* if number of messages equal 0*/
> + if (num == 0) {
> + mutex_unlock(&i2c->lock);
> + pm_runtime_put(i2c->dev);
> + return 0;
> + }
you could have moved the check above the pm_runtime_get and avoided a
pile of checks. not necessary to fix though.
> +
> + for (i = 1; i < num; i++) {
> + /* Message address equal? */
> + if (unlikely(intel_mid_i2c_address_neq(&pmsg[0], &pmsg[i]))) {
> + dev_err(&adap->dev, "Invalid address in msg[%d]\n", i);
> + mutex_unlock(&i2c->lock);
> + pm_runtime_put(i2c->dev);
> + return -EINVAL;
> + }
> + }
can you really not support having a different address in one of the
message segments? surely if sending a restart then this should be
possible?
> + if (intel_mid_i2c_setup(adap, pmsg)) {
> + mutex_unlock(&i2c->lock);
> + pm_runtime_put(i2c->dev);
> + return -EINVAL;
> + }
> +
> + for (i = 0; i < num; i++) {
> + i2c->msg = pmsg;
> + i2c->status = STATUS_IDLE;
> + /* Read or Write */
> + if (pmsg->flags & I2C_M_RD) {
> + dev_dbg(&adap->dev, "I2C_M_RD\n");
> + err = xfer_read(adap, pmsg->buf, pmsg->len);
> + } else {
> + dev_dbg(&adap->dev, "I2C_M_WR\n");
> + err = xfer_write(adap, pmsg->buf, pmsg->len);
> + }
> + if (err < 0)
> + goto err_1;
> + dev_dbg(&adap->dev, "msg[%d] transfer complete\n", i);
> + pmsg++; /* next message */
> + }
> + goto exit;
> +
> +err_1:
> + i = err;
firstly, why assing i=err, you could just return err below.
secondly, given xfer_read and xfer_write return 0 on success
then you can just skip the goto exit stage after the loop.
> +exit:
> + /* Mask interrupts */
> + writel(0x0000, i2c->base + IC_INTR_MASK);
> + /* Clear all interrupts */
> + readl(i2c->base + IC_CLR_INTR);
> +
> + i2c->status = STATUS_IDLE;
> + mutex_unlock(&i2c->lock);
> + pm_runtime_put(i2c->dev);
> +
> + return i;
> +}
> +
> +static int intel_mid_i2c_runtime_suspend(struct device *dev)
> +{
> + struct pci_dev *pdev = to_pci_dev(dev);
> + struct intel_mid_i2c_private *i2c =
> + (struct intel_mid_i2c_private *)pci_get_drvdata(pdev);
no need to cast here.
> + struct i2c_adapter *adap = to_i2c_adapter(dev);
> + int err;
> +
> + if (i2c->status != STATUS_IDLE)
> + return -1;
> +
> + intel_mid_i2c_disable(adap);
> +
> + err = pci_save_state(pdev);
> + if (err) {
> + dev_err(dev, "pci_save_state failed\n");
> + return err;
> + }
> +
> + err = pci_set_power_state(pdev, PCI_D3hot);
> + if (err) {
> + dev_err(dev, "pci_set_power_state failed\n");
> + return err;
> + }
> + i2c->status = STATUS_STANDBY;
> +
> + return 0;
> +}
> +
> +static int intel_mid_i2c_runtime_resume(struct device *dev)
> +{
> + struct pci_dev *pdev = to_pci_dev(dev);
> + struct intel_mid_i2c_private *i2c =
> + (struct intel_mid_i2c_private *)pci_get_drvdata(pdev);
ditto.
> + int err;
> +
> + if (i2c->status != STATUS_STANDBY)
> + return 0;
> +
> + pci_set_power_state(pdev, PCI_D0);
> + pci_restore_state(pdev);
> + err = pci_enable_device(pdev);
> + if (err) {
> + dev_err(dev, "pci_enable_device failed\n");
> + return err;
> + }
> +
> + i2c->status = STATUS_IDLE;
> +
> + intel_mid_i2c_hwinit(i2c);
> + return err;
> +}
> +
> +static void i2c_isr_read(struct intel_mid_i2c_private *i2c)
> +{
> + struct i2c_msg *msg = i2c->msg;
> + int rx_num;
> + u32 len;
> + u8 *buf;
> +
> + if (!(msg->flags & I2C_M_RD))
> + return;
> +
> + if (i2c->status != STATUS_READ_IN_PROGRESS) {
> + len = msg->len;
> + buf = msg->buf;
> + } else {
> + len = i2c->rx_buf_len;
> + buf = i2c->rx_buf;
> + }
> +
> + rx_num = readl(i2c->base + IC_RXFLR);
> +
> + for (; len > 0 && rx_num > 0; len--, rx_num--)
> + *buf++ = readl(i2c->base + IC_DATA_CMD);
> +
> + if (len > 0) {
> + i2c->status = STATUS_READ_IN_PROGRESS;
> + i2c->rx_buf_len = len;
> + i2c->rx_buf = buf;
> + } else
> + i2c->status = STATUS_READ_SUCCESS;
> +
> + return;
> +}
> +
> +static irqreturn_t intel_mid_i2c_isr(int this_irq, void *dev)
> +{
> + struct intel_mid_i2c_private *i2c = dev;
> + u32 stat = readl(i2c->base + IC_INTR_STAT);
> +
> + if (!stat)
> + return IRQ_NONE;
> +
> + dev_dbg(&i2c->adap.dev, "%s, stat = 0x%x\n", __func__, stat);
> + stat &= 0x54;
> +
> + if (i2c->status != STATUS_WRITE_START &&
> + i2c->status != STATUS_READ_START &&
> + i2c->status != STATUS_READ_IN_PROGRESS)
> + goto err;
> +
> + if (stat & TX_ABRT)
> + i2c->abort = readl(i2c->base + IC_TX_ABRT_SOURCE);
> +
> + readl(i2c->base + IC_CLR_INTR);
> +
> + if (stat & TX_ABRT) {
> + intel_mid_i2c_abort(i2c);
> + goto exit;
> + }
> +
> + if (stat & RX_FULL) {
> + i2c_isr_read(i2c);
> + goto exit;
> + }
> +
> + if (stat & TX_EMPTY) {
> + if (readl(i2c->base + IC_STATUS) & 0x4)
> + i2c->status = STATUS_WRITE_SUCCESS;
> + }
> +
> +exit:
> + if (i2c->status == STATUS_READ_SUCCESS ||
> + i2c->status == STATUS_WRITE_SUCCESS ||
> + i2c->status == STATUS_XFER_ABORT) {
> + /* Clear all interrupts */
> + readl(i2c->base + IC_CLR_INTR);
> + /* Mask interrupts */
> + writel(0, i2c->base + IC_INTR_MASK);
> + complete(&i2c->complete);
> + }
> +err:
> + return IRQ_HANDLED;
> +}
> +
rest of the driver looks ok.
next prev parent reply other threads:[~2010-10-26 22:54 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-10-22 14:05 [PATCH] I2C driver supporting Moorestown and Medfield platform Alan Cox
[not found] ` <20101022140431.3545.37799.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2010-10-26 8:08 ` Jean Delvare
[not found] ` <20101026100800.017c5aaa-R0o5gVi9kd7kN2dkZ6Wm7A@public.gmane.org>
2010-10-26 13:14 ` Ben Dooks
2010-10-26 22:54 ` Ben Dooks [this message]
-- strict thread matches above, loose matches on Subject: below --
2010-10-27 11:44 Alan Cox
[not found] ` <20101027114205.11696.76731.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2010-10-28 8:58 ` Ben Dooks
2010-10-14 14:33 Alan Cox
2010-10-14 14:27 Alan Cox
2010-08-27 15:21 Alan Cox
2010-08-03 14:33 Alan Cox
2010-07-19 15:45 Alan Cox
2010-07-19 10:17 Alan Cox
[not found] ` <20100719101724.31685.76712.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2010-07-19 12:32 ` Jean Delvare
[not found] ` <20100719143244.2be29ecc-ig7AzVSIIG7kN2dkZ6Wm7A@public.gmane.org>
2010-07-19 13:08 ` Alan Cox
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4CC75C14.3000101@fluff.org \
--to=ben-linux-elnmno+kys3ytjvyw6ydsg@public.gmane.org \
--cc=alan-qBU/x9rampVanCEyBjwyrvXRex20P6io@public.gmane.org \
--cc=khali-PUYAD+kWke1g9hUCZPvPmw@public.gmane.org \
--cc=linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).