diff options
Diffstat (limited to 'drivers/i2c/busses/i2c-sh_mobile.c')
| -rw-r--r-- | drivers/i2c/busses/i2c-sh_mobile.c | 451 |
1 files changed, 263 insertions, 188 deletions
diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c index 8110ca45f34..8b5e79cb446 100644 --- a/drivers/i2c/busses/i2c-sh_mobile.c +++ b/drivers/i2c/busses/i2c-sh_mobile.c @@ -27,32 +27,32 @@ #include <linux/platform_device.h> #include <linux/interrupt.h> #include <linux/i2c.h> -#include <linux/of_i2c.h> #include <linux/err.h> #include <linux/pm_runtime.h> #include <linux/clk.h> #include <linux/io.h> #include <linux/slab.h> +#include <linux/of_device.h> #include <linux/i2c/i2c-sh_mobile.h> /* Transmit operation: */ /* */ /* 0 byte transmit */ -/* BUS: S A8 ACK P */ +/* BUS: S A8 ACK P(*) */ /* IRQ: DTE WAIT */ /* ICIC: */ /* ICCR: 0x94 0x90 */ /* ICDR: A8 */ /* */ /* 1 byte transmit */ -/* BUS: S A8 ACK D8(1) ACK P */ +/* BUS: S A8 ACK D8(1) ACK P(*) */ /* IRQ: DTE WAIT WAIT */ /* ICIC: -DTE */ /* ICCR: 0x94 0x90 */ /* ICDR: A8 D8(1) */ /* */ /* 2 byte transmit */ -/* BUS: S A8 ACK D8(1) ACK D8(2) ACK P */ +/* BUS: S A8 ACK D8(1) ACK D8(2) ACK P(*) */ /* IRQ: DTE WAIT WAIT WAIT */ /* ICIC: -DTE */ /* ICCR: 0x94 0x90 */ @@ -66,20 +66,20 @@ /* 0 byte receive - not supported since slave may hold SDA low */ /* */ /* 1 byte receive [TX] | [RX] */ -/* BUS: S A8 ACK | D8(1) ACK P */ +/* BUS: S A8 ACK | D8(1) ACK P(*) */ /* IRQ: DTE WAIT | WAIT DTE */ /* ICIC: -DTE | +DTE */ /* ICCR: 0x94 0x81 | 0xc0 */ /* ICDR: A8 | D8(1) */ /* */ /* 2 byte receive [TX]| [RX] */ -/* BUS: S A8 ACK | D8(1) ACK D8(2) ACK P */ +/* BUS: S A8 ACK | D8(1) ACK D8(2) ACK P(*) */ /* IRQ: DTE WAIT | WAIT WAIT DTE */ /* ICIC: -DTE | +DTE */ /* ICCR: 0x94 0x81 | 0xc0 */ /* ICDR: A8 | D8(1) D8(2) */ /* */ -/* 3 byte receive [TX] | [RX] */ +/* 3 byte receive [TX] | [RX] (*) */ /* BUS: S A8 ACK | D8(1) ACK D8(2) ACK D8(3) ACK P */ /* IRQ: DTE WAIT | WAIT WAIT WAIT DTE */ /* ICIC: -DTE | +DTE */ @@ -94,7 +94,7 @@ /* SDA ___\___XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXAAAAAAAAA___/ */ /* SCL \_/1\_/2\_/3\_/4\_/5\_/6\_/7\_/8\___/9\_____/ */ /* */ -/* S D7 D6 D5 D4 D3 D2 D1 D0 P */ +/* S D7 D6 D5 D4 D3 D2 D1 D0 P(*) */ /* ___ */ /* WAIT IRQ ________________________________/ \___________ */ /* TACK IRQ ____________________________________/ \_______ */ @@ -103,6 +103,11 @@ /* _______________________________________________ */ /* BUSY __/ \_ */ /* */ +/* (*) The STOP condition is only sent by the master at the end of the last */ +/* I2C message or if the I2C_M_STOP flag is set. Similarly, the BUSY bit is */ +/* only cleared after the STOP condition, so, between messages we have to */ +/* poll for the DTE bit. */ +/* */ enum sh_mobile_i2c_op { OP_START = 0, @@ -120,22 +125,29 @@ struct sh_mobile_i2c_data { void __iomem *reg; struct i2c_adapter adap; unsigned long bus_speed; + unsigned int clks_per_count; struct clk *clk; u_int8_t icic; - u_int8_t iccl; - u_int8_t icch; u_int8_t flags; + u_int16_t iccl; + u_int16_t icch; spinlock_t lock; wait_queue_head_t wait; struct i2c_msg *msg; int pos; int sr; + bool send_stop; +}; + +struct sh_mobile_dt_config { + int clks_per_count; }; #define IIC_FLAG_HAS_ICIC67 (1 << 0) -#define NORMAL_SPEED 100000 /* FAST_SPEED 400000 */ +#define STANDARD_MODE 100000 +#define FAST_MODE 400000 /* Register offsets */ #define ICDR 0x00 @@ -187,57 +199,96 @@ static void iic_set_clr(struct sh_mobile_i2c_data *pd, int offs, iic_wr(pd, offs, (iic_rd(pd, offs) | set) & ~clr); } -static void activate_ch(struct sh_mobile_i2c_data *pd) +static u32 sh_mobile_i2c_iccl(unsigned long count_khz, u32 tLOW, u32 tf) { - unsigned long i2c_clk; - u_int32_t num; - u_int32_t denom; - u_int32_t tmp; + /* + * Conditional expression: + * ICCL >= COUNT_CLK * (tLOW + tf) + * + * SH-Mobile IIC hardware starts counting the LOW period of + * the SCL signal (tLOW) as soon as it pulls the SCL line. + * In order to meet the tLOW timing spec, we need to take into + * account the fall time of SCL signal (tf). Default tf value + * should be 0.3 us, for safety. + */ + return (((count_khz * (tLOW + tf)) + 5000) / 10000); +} - /* Wake up device and enable clock */ - pm_runtime_get_sync(pd->dev); - clk_enable(pd->clk); +static u32 sh_mobile_i2c_icch(unsigned long count_khz, u32 tHIGH, u32 tf) +{ + /* + * Conditional expression: + * ICCH >= COUNT_CLK * (tHIGH + tf) + * + * SH-Mobile IIC hardware is aware of SCL transition period 'tr', + * and can ignore it. SH-Mobile IIC controller starts counting + * the HIGH period of the SCL signal (tHIGH) after the SCL input + * voltage increases at VIH. + * + * Afterward it turned out calculating ICCH using only tHIGH spec + * will result in violation of the tHD;STA timing spec. We need + * to take into account the fall time of SDA signal (tf) at START + * condition, in order to meet both tHIGH and tHD;STA specs. + */ + return (((count_khz * (tHIGH + tf)) + 5000) / 10000); +} + +static int sh_mobile_i2c_init(struct sh_mobile_i2c_data *pd) +{ + unsigned long i2c_clk_khz; + u32 tHIGH, tLOW, tf; + uint16_t max_val; /* Get clock rate after clock is enabled */ - i2c_clk = clk_get_rate(pd->clk); + clk_prepare_enable(pd->clk); + i2c_clk_khz = clk_get_rate(pd->clk) / 1000; + clk_disable_unprepare(pd->clk); + i2c_clk_khz /= pd->clks_per_count; + + if (pd->bus_speed == STANDARD_MODE) { + tLOW = 47; /* tLOW = 4.7 us */ + tHIGH = 40; /* tHD;STA = tHIGH = 4.0 us */ + tf = 3; /* tf = 0.3 us */ + } else if (pd->bus_speed == FAST_MODE) { + tLOW = 13; /* tLOW = 1.3 us */ + tHIGH = 6; /* tHD;STA = tHIGH = 0.6 us */ + tf = 3; /* tf = 0.3 us */ + } else { + dev_err(pd->dev, "unrecognized bus speed %lu Hz\n", + pd->bus_speed); + return -EINVAL; + } - /* Calculate the value for iccl. From the data sheet: - * iccl = (p clock / transfer rate) * (L / (L + H)) - * where L and H are the SCL low/high ratio (5/4 in this case). - * We also round off the result. - */ - num = i2c_clk * 5; - denom = pd->bus_speed * 9; - tmp = num * 10 / denom; - if (tmp % 10 >= 5) - pd->iccl = (u_int8_t)((num/denom) + 1); - else - pd->iccl = (u_int8_t)(num/denom); + pd->iccl = sh_mobile_i2c_iccl(i2c_clk_khz, tLOW, tf); + pd->icch = sh_mobile_i2c_icch(i2c_clk_khz, tHIGH, tf); - /* one more bit of ICCL in ICIC */ - if (pd->flags & IIC_FLAG_HAS_ICIC67) { - if ((num/denom) > 0xff) - pd->icic |= ICIC_ICCLB8; - else - pd->icic &= ~ICIC_ICCLB8; + max_val = pd->flags & IIC_FLAG_HAS_ICIC67 ? 0x1ff : 0xff; + if (pd->iccl > max_val || pd->icch > max_val) { + dev_err(pd->dev, "timing values out of range: L/H=0x%x/0x%x\n", + pd->iccl, pd->icch); + return -EINVAL; } - /* Calculate the value for icch. From the data sheet: - icch = (p clock / transfer rate) * (H / (L + H)) */ - num = i2c_clk * 4; - tmp = num * 10 / denom; - if (tmp % 10 >= 5) - pd->icch = (u_int8_t)((num/denom) + 1); + /* one more bit of ICCL in ICIC */ + if (pd->iccl & 0x100) + pd->icic |= ICIC_ICCLB8; else - pd->icch = (u_int8_t)(num/denom); + pd->icic &= ~ICIC_ICCLB8; /* one more bit of ICCH in ICIC */ - if (pd->flags & IIC_FLAG_HAS_ICIC67) { - if ((num/denom) > 0xff) - pd->icic |= ICIC_ICCHB8; - else - pd->icic &= ~ICIC_ICCHB8; - } + if (pd->icch & 0x100) + pd->icic |= ICIC_ICCHB8; + else + pd->icic &= ~ICIC_ICCHB8; + + return 0; +} + +static void activate_ch(struct sh_mobile_i2c_data *pd) +{ + /* Wake up device and enable clock */ + pm_runtime_get_sync(pd->dev); + clk_prepare_enable(pd->clk); /* Enable channel and configure rx ack */ iic_set_clr(pd, ICCR, ICCR_ICE, 0); @@ -246,8 +297,8 @@ static void activate_ch(struct sh_mobile_i2c_data *pd) iic_wr(pd, ICIC, 0); /* Set the clock */ - iic_wr(pd, ICCL, pd->iccl); - iic_wr(pd, ICCH, pd->icch); + iic_wr(pd, ICCL, pd->iccl & 0xff); + iic_wr(pd, ICCH, pd->icch & 0xff); } static void deactivate_ch(struct sh_mobile_i2c_data *pd) @@ -260,7 +311,7 @@ static void deactivate_ch(struct sh_mobile_i2c_data *pd) iic_set_clr(pd, ICCR, 0, ICCR_ICE); /* Disable clock and mark device as idle */ - clk_disable(pd->clk); + clk_disable_unprepare(pd->clk); pm_runtime_put_sync(pd->dev); } @@ -276,7 +327,7 @@ static unsigned char i2c_op(struct sh_mobile_i2c_data *pd, switch (op) { case OP_START: /* issue start and trigger DTE interrupt */ - iic_wr(pd, ICCR, 0x94); + iic_wr(pd, ICCR, ICCR_ICE | ICCR_TRS | ICCR_BBSY); break; case OP_TX_FIRST: /* disable DTE interrupt and write data */ iic_wr(pd, ICIC, ICIC_WAITE | ICIC_ALE | ICIC_TACKE); @@ -287,10 +338,11 @@ static unsigned char i2c_op(struct sh_mobile_i2c_data *pd, break; case OP_TX_STOP: /* write data and issue a stop afterwards */ iic_wr(pd, ICDR, data); - iic_wr(pd, ICCR, 0x90); + iic_wr(pd, ICCR, pd->send_stop ? ICCR_ICE | ICCR_TRS + : ICCR_ICE | ICCR_TRS | ICCR_BBSY); break; case OP_TX_TO_RX: /* select read mode */ - iic_wr(pd, ICCR, 0x81); + iic_wr(pd, ICCR, ICCR_ICE | ICCR_SCP); break; case OP_RX: /* just read data */ ret = iic_rd(pd, ICDR); @@ -298,13 +350,13 @@ static unsigned char i2c_op(struct sh_mobile_i2c_data *pd, case OP_RX_STOP: /* enable DTE interrupt, issue stop */ iic_wr(pd, ICIC, ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE); - iic_wr(pd, ICCR, 0xc0); + iic_wr(pd, ICCR, ICCR_ICE | ICCR_RACK); break; case OP_RX_STOP_DATA: /* enable DTE interrupt, read data, issue stop */ iic_wr(pd, ICIC, ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE); ret = iic_rd(pd, ICDR); - iic_wr(pd, ICCR, 0xc0); + iic_wr(pd, ICCR, ICCR_ICE | ICCR_RACK); break; } @@ -314,20 +366,14 @@ static unsigned char i2c_op(struct sh_mobile_i2c_data *pd, return ret; } -static int sh_mobile_i2c_is_first_byte(struct sh_mobile_i2c_data *pd) +static bool sh_mobile_i2c_is_first_byte(struct sh_mobile_i2c_data *pd) { - if (pd->pos == -1) - return 1; - - return 0; + return pd->pos == -1; } -static int sh_mobile_i2c_is_last_byte(struct sh_mobile_i2c_data *pd) +static bool sh_mobile_i2c_is_last_byte(struct sh_mobile_i2c_data *pd) { - if (pd->pos == (pd->msg->len - 1)) - return 1; - - return 0; + return pd->pos == pd->msg->len - 1; } static void sh_mobile_i2c_get_data(struct sh_mobile_i2c_data *pd, @@ -434,25 +480,31 @@ static irqreturn_t sh_mobile_i2c_isr(int irq, void *dev_id) wake_up(&pd->wait); } + /* defeat write posting to avoid spurious WAIT interrupts */ + iic_rd(pd, ICSR); + return IRQ_HANDLED; } -static int start_ch(struct sh_mobile_i2c_data *pd, struct i2c_msg *usr_msg) +static int start_ch(struct sh_mobile_i2c_data *pd, struct i2c_msg *usr_msg, + bool do_init) { if (usr_msg->len == 0 && (usr_msg->flags & I2C_M_RD)) { dev_err(pd->dev, "Unsupported zero length i2c read\n"); - return -EIO; + return -EOPNOTSUPP; } - /* Initialize channel registers */ - iic_set_clr(pd, ICCR, 0, ICCR_ICE); + if (do_init) { + /* Initialize channel registers */ + iic_set_clr(pd, ICCR, 0, ICCR_ICE); - /* Enable channel and configure rx ack */ - iic_set_clr(pd, ICCR, ICCR_ICE, 0); + /* Enable channel and configure rx ack */ + iic_set_clr(pd, ICCR, ICCR_ICE, 0); - /* Set the clock */ - iic_wr(pd, ICCL, pd->iccl); - iic_wr(pd, ICCH, pd->icch); + /* Set the clock */ + iic_wr(pd, ICCL, pd->iccl & 0xff); + iic_wr(pd, ICCH, pd->icch & 0xff); + } pd->msg = usr_msg; pd->pos = -1; @@ -463,6 +515,54 @@ static int start_ch(struct sh_mobile_i2c_data *pd, struct i2c_msg *usr_msg) return 0; } +static int poll_dte(struct sh_mobile_i2c_data *pd) +{ + int i; + + for (i = 1000; i; i--) { + u_int8_t val = iic_rd(pd, ICSR); + + if (val & ICSR_DTE) + break; + + if (val & ICSR_TACK) + return -ENXIO; + + udelay(10); + } + + return i ? 0 : -ETIMEDOUT; +} + +static int poll_busy(struct sh_mobile_i2c_data *pd) +{ + int i; + + for (i = 1000; i; i--) { + u_int8_t val = iic_rd(pd, ICSR); + + dev_dbg(pd->dev, "val 0x%02x pd->sr 0x%02x\n", val, pd->sr); + + /* the interrupt handler may wake us up before the + * transfer is finished, so poll the hardware + * until we're done. + */ + if (!(val & ICSR_BUSY)) { + /* handle missing acknowledge and arbitration lost */ + val |= pd->sr; + if (val & ICSR_TACK) + return -ENXIO; + if (val & ICSR_AL) + return -EAGAIN; + break; + } + + udelay(10); + } + + return i ? 0 : -ETIMEDOUT; +} + static int sh_mobile_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num) @@ -470,53 +570,39 @@ static int sh_mobile_i2c_xfer(struct i2c_adapter *adapter, struct sh_mobile_i2c_data *pd = i2c_get_adapdata(adapter); struct i2c_msg *msg; int err = 0; - u_int8_t val; - int i, k, retry_count; + int i, k; activate_ch(pd); /* Process all messages */ for (i = 0; i < num; i++) { + bool do_start = pd->send_stop || !i; msg = &msgs[i]; + pd->send_stop = i == num - 1 || msg->flags & I2C_M_STOP; - err = start_ch(pd, msg); + err = start_ch(pd, msg, do_start); if (err) break; - i2c_op(pd, OP_START, 0); + if (do_start) + i2c_op(pd, OP_START, 0); /* The interrupt handler takes care of the rest... */ k = wait_event_timeout(pd->wait, pd->sr & (ICSR_TACK | SW_DONE), 5 * HZ); - if (!k) + if (!k) { dev_err(pd->dev, "Transfer request timed out\n"); - - retry_count = 1000; -again: - val = iic_rd(pd, ICSR); - - dev_dbg(pd->dev, "val 0x%02x pd->sr 0x%02x\n", val, pd->sr); - - /* the interrupt handler may wake us up before the - * transfer is finished, so poll the hardware - * until we're done. - */ - if (val & ICSR_BUSY) { - udelay(10); - if (retry_count--) - goto again; - - err = -EIO; - dev_err(pd->dev, "Polling timed out\n"); + err = -ETIMEDOUT; break; } - /* handle missing acknowledge and arbitration lost */ - if ((val | pd->sr) & (ICSR_TACK | ICSR_AL)) { - err = -EIO; + if (pd->send_stop) + err = poll_busy(pd); + else + err = poll_dte(pd); + if (err < 0) break; - } } deactivate_ch(pd); @@ -528,7 +614,7 @@ again: static u32 sh_mobile_i2c_func(struct i2c_adapter *adapter) { - return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_PROTOCOL_MANGLING; } static struct i2c_algorithm sh_mobile_i2c_algorithm = { @@ -536,102 +622,111 @@ static struct i2c_algorithm sh_mobile_i2c_algorithm = { .master_xfer = sh_mobile_i2c_xfer, }; -static int sh_mobile_i2c_hook_irqs(struct platform_device *dev, int hook) +static const struct sh_mobile_dt_config default_dt_config = { + .clks_per_count = 1, +}; + +static const struct sh_mobile_dt_config rcar_gen2_dt_config = { + .clks_per_count = 2, +}; + +static const struct of_device_id sh_mobile_i2c_dt_ids[] = { + { .compatible = "renesas,rmobile-iic", .data = &default_dt_config }, + { .compatible = "renesas,iic-r8a7790", .data = &rcar_gen2_dt_config }, + { .compatible = "renesas,iic-r8a7791", .data = &rcar_gen2_dt_config }, + { .compatible = "renesas,iic-r8a7792", .data = &rcar_gen2_dt_config }, + { .compatible = "renesas,iic-r8a7793", .data = &rcar_gen2_dt_config }, + { .compatible = "renesas,iic-r8a7794", .data = &rcar_gen2_dt_config }, + {}, +}; +MODULE_DEVICE_TABLE(of, sh_mobile_i2c_dt_ids); + +static int sh_mobile_i2c_hook_irqs(struct platform_device *dev) { struct resource *res; - int ret = -ENXIO; - int n, k = 0; + resource_size_t n; + int k = 0, ret; while ((res = platform_get_resource(dev, IORESOURCE_IRQ, k))) { - for (n = res->start; hook && n <= res->end; n++) { - if (request_irq(n, sh_mobile_i2c_isr, 0, - dev_name(&dev->dev), dev)) { - for (n--; n >= res->start; n--) - free_irq(n, dev); - - goto rollback; + for (n = res->start; n <= res->end; n++) { + ret = devm_request_irq(&dev->dev, n, sh_mobile_i2c_isr, + 0, dev_name(&dev->dev), dev); + if (ret) { + dev_err(&dev->dev, "cannot request IRQ %pa\n", &n); + return ret; } } k++; } - if (hook) - return k > 0 ? 0 : -ENOENT; - - ret = 0; - - rollback: - k--; - - while (k >= 0) { - res = platform_get_resource(dev, IORESOURCE_IRQ, k); - for (n = res->start; n <= res->end; n++) - free_irq(n, dev); - - k--; - } - - return ret; + return k > 0 ? 0 : -ENOENT; } static int sh_mobile_i2c_probe(struct platform_device *dev) { - struct i2c_sh_mobile_platform_data *pdata = dev->dev.platform_data; + struct i2c_sh_mobile_platform_data *pdata = dev_get_platdata(&dev->dev); struct sh_mobile_i2c_data *pd; struct i2c_adapter *adap; struct resource *res; - int size; int ret; + u32 bus_speed; - pd = kzalloc(sizeof(struct sh_mobile_i2c_data), GFP_KERNEL); - if (pd == NULL) { - dev_err(&dev->dev, "cannot allocate private data\n"); + pd = devm_kzalloc(&dev->dev, sizeof(struct sh_mobile_i2c_data), GFP_KERNEL); + if (!pd) return -ENOMEM; - } - pd->clk = clk_get(&dev->dev, NULL); + pd->clk = devm_clk_get(&dev->dev, NULL); if (IS_ERR(pd->clk)) { dev_err(&dev->dev, "cannot get clock\n"); - ret = PTR_ERR(pd->clk); - goto err; + return PTR_ERR(pd->clk); } - ret = sh_mobile_i2c_hook_irqs(dev, 1); - if (ret) { - dev_err(&dev->dev, "cannot request IRQ\n"); - goto err_clk; - } + ret = sh_mobile_i2c_hook_irqs(dev); + if (ret) + return ret; pd->dev = &dev->dev; platform_set_drvdata(dev, pd); res = platform_get_resource(dev, IORESOURCE_MEM, 0); - if (res == NULL) { - dev_err(&dev->dev, "cannot find IO resource\n"); - ret = -ENOENT; - goto err_irq; - } - size = resource_size(res); + pd->reg = devm_ioremap_resource(&dev->dev, res); + if (IS_ERR(pd->reg)) + return PTR_ERR(pd->reg); - pd->reg = ioremap(res->start, size); - if (pd->reg == NULL) { - dev_err(&dev->dev, "cannot map IO\n"); - ret = -ENXIO; - goto err_irq; - } + /* Use platform data bus speed or STANDARD_MODE */ + ret = of_property_read_u32(dev->dev.of_node, "clock-frequency", &bus_speed); + pd->bus_speed = ret ? STANDARD_MODE : bus_speed; + + pd->clks_per_count = 1; + + if (dev->dev.of_node) { + const struct of_device_id *match; - /* Use platformd data bus speed or NORMAL_SPEED */ - pd->bus_speed = NORMAL_SPEED; - if (pdata && pdata->bus_speed) - pd->bus_speed = pdata->bus_speed; + match = of_match_device(sh_mobile_i2c_dt_ids, &dev->dev); + if (match) { + const struct sh_mobile_dt_config *config; + + config = match->data; + pd->clks_per_count = config->clks_per_count; + } + } else { + if (pdata && pdata->bus_speed) + pd->bus_speed = pdata->bus_speed; + if (pdata && pdata->clks_per_count) + pd->clks_per_count = pdata->clks_per_count; + } /* The IIC blocks on SH-Mobile ARM processors * come with two new bits in ICIC. */ - if (size > 0x17) + if (resource_size(res) > 0x17) pd->flags |= IIC_FLAG_HAS_ICIC67; + ret = sh_mobile_i2c_init(pd); + if (ret) + return ret; + /* Enable Runtime PM for this device. * * Also tell the Runtime PM core to ignore children @@ -664,24 +759,14 @@ static int sh_mobile_i2c_probe(struct platform_device *dev) ret = i2c_add_numbered_adapter(adap); if (ret < 0) { dev_err(&dev->dev, "cannot add numbered adapter\n"); - goto err_all; + return ret; } - dev_info(&dev->dev, "I2C adapter %d with bus speed %lu Hz\n", - adap->nr, pd->bus_speed); + dev_info(&dev->dev, + "I2C adapter %d with bus speed %lu Hz (L/H=0x%x/0x%x)\n", + adap->nr, pd->bus_speed, pd->iccl, pd->icch); - of_i2c_register_devices(adap); return 0; - - err_all: - iounmap(pd->reg); - err_irq: - sh_mobile_i2c_hook_irqs(dev, 0); - err_clk: - clk_put(pd->clk); - err: - kfree(pd); - return ret; } static int sh_mobile_i2c_remove(struct platform_device *dev) @@ -689,11 +774,7 @@ static int sh_mobile_i2c_remove(struct platform_device *dev) struct sh_mobile_i2c_data *pd = platform_get_drvdata(dev); i2c_del_adapter(&pd->adap); - iounmap(pd->reg); - sh_mobile_i2c_hook_irqs(dev, 0); - clk_put(pd->clk); pm_runtime_disable(&dev->dev); - kfree(pd); return 0; } @@ -714,12 +795,6 @@ static const struct dev_pm_ops sh_mobile_i2c_dev_pm_ops = { .runtime_resume = sh_mobile_i2c_runtime_nop, }; -static const struct of_device_id sh_mobile_i2c_dt_ids[] __devinitconst = { - { .compatible = "renesas,rmobile-iic", }, - {}, -}; -MODULE_DEVICE_TABLE(of, sh_mobile_i2c_dt_ids); - static struct platform_driver sh_mobile_i2c_driver = { .driver = { .name = "i2c-sh_mobile", |
