mirror of
https://github.com/torvalds/linux.git
synced 2024-12-28 05:41:55 +00:00
Fixed a build error following the major refactoring involving the
VIA-I2C modules. Originally, the code was split to group together parts that would be used by different drivers. This caused build issues when two modules linked to the same code. -----BEGIN PGP SIGNATURE----- iIwEABYIADQWIQScDfrjQa34uOld1VLaeAVmJtMtbgUCZn6IhhYcYW5kaS5zaHl0 aUBrZXJuZWwub3JnAAoJENp4BWYm0y1uOekA/2RfIlWh367KrZVl17iOYDZt4PC5 UN8upYT2063exlc5AP953/DQkr0xGBGYYZH7q1xBmkTkYV3G0QSTKKcTwNo6DQ== =tKNc -----END PGP SIGNATURE----- Merge tag 'i2c-host-fixes-6.10-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/andi.shyti/linux into i2c/for-current Fixed a build error following the major refactoring involving the VIA-I2C modules. Originally, the code was split to group together parts that would be used by different drivers. This caused build issues when two modules linked to the same code.
This commit is contained in:
commit
4e9a1a47c5
@ -29,8 +29,7 @@ obj-$(CONFIG_I2C_SIS630) += i2c-sis630.o
|
||||
obj-$(CONFIG_I2C_SIS96X) += i2c-sis96x.o
|
||||
obj-$(CONFIG_I2C_VIA) += i2c-via.o
|
||||
obj-$(CONFIG_I2C_VIAPRO) += i2c-viapro.o
|
||||
i2c-zhaoxin-objs := i2c-viai2c-zhaoxin.o i2c-viai2c-common.o
|
||||
obj-$(CONFIG_I2C_ZHAOXIN) += i2c-zhaoxin.o
|
||||
obj-$(CONFIG_I2C_ZHAOXIN) += i2c-viai2c-zhaoxin.o i2c-viai2c-common.o
|
||||
|
||||
# Mac SMBus host controller drivers
|
||||
obj-$(CONFIG_I2C_HYDRA) += i2c-hydra.o
|
||||
@ -120,8 +119,7 @@ obj-$(CONFIG_I2C_TEGRA_BPMP) += i2c-tegra-bpmp.o
|
||||
obj-$(CONFIG_I2C_UNIPHIER) += i2c-uniphier.o
|
||||
obj-$(CONFIG_I2C_UNIPHIER_F) += i2c-uniphier-f.o
|
||||
obj-$(CONFIG_I2C_VERSATILE) += i2c-versatile.o
|
||||
i2c-wmt-objs := i2c-viai2c-wmt.o i2c-viai2c-common.o
|
||||
obj-$(CONFIG_I2C_WMT) += i2c-wmt.o
|
||||
obj-$(CONFIG_I2C_WMT) += i2c-viai2c-wmt.o i2c-viai2c-common.o
|
||||
i2c-octeon-objs := i2c-octeon-core.o i2c-octeon-platdrv.o
|
||||
obj-$(CONFIG_I2C_OCTEON) += i2c-octeon.o
|
||||
i2c-thunderx-objs := i2c-octeon-core.o i2c-thunderx-pcidrv.o
|
||||
|
@ -17,6 +17,7 @@ int viai2c_wait_bus_not_busy(struct viai2c *i2c)
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(viai2c_wait_bus_not_busy);
|
||||
|
||||
static int viai2c_write(struct viai2c *i2c, struct i2c_msg *pmsg, int last)
|
||||
{
|
||||
@ -121,6 +122,7 @@ int viai2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
|
||||
|
||||
return (ret < 0) ? ret : i;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(viai2c_xfer);
|
||||
|
||||
/*
|
||||
* Main process of the byte mode xfer
|
||||
@ -130,7 +132,7 @@ int viai2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
|
||||
* 0: there is still data that needs to be transferred
|
||||
* -EIO: error occurred
|
||||
*/
|
||||
static int viai2c_irq_xfer(struct viai2c *i2c)
|
||||
int viai2c_irq_xfer(struct viai2c *i2c)
|
||||
{
|
||||
u16 val;
|
||||
struct i2c_msg *msg = i2c->msg;
|
||||
@ -171,51 +173,11 @@ static int viai2c_irq_xfer(struct viai2c *i2c)
|
||||
|
||||
return i2c->xfered_len == msg->len;
|
||||
}
|
||||
|
||||
int __weak viai2c_fifo_irq_xfer(struct viai2c *i2c, bool irq)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static irqreturn_t viai2c_isr(int irq, void *data)
|
||||
{
|
||||
struct viai2c *i2c = data;
|
||||
u8 status;
|
||||
|
||||
/* save the status and write-clear it */
|
||||
status = readw(i2c->base + VIAI2C_REG_ISR);
|
||||
if (!status && i2c->platform == VIAI2C_PLAT_ZHAOXIN)
|
||||
return IRQ_NONE;
|
||||
|
||||
writew(status, i2c->base + VIAI2C_REG_ISR);
|
||||
|
||||
i2c->ret = 0;
|
||||
if (status & VIAI2C_ISR_NACK_ADDR)
|
||||
i2c->ret = -EIO;
|
||||
|
||||
if (i2c->platform == VIAI2C_PLAT_WMT && (status & VIAI2C_ISR_SCL_TIMEOUT))
|
||||
i2c->ret = -ETIMEDOUT;
|
||||
|
||||
if (!i2c->ret) {
|
||||
if (i2c->mode == VIAI2C_BYTE_MODE)
|
||||
i2c->ret = viai2c_irq_xfer(i2c);
|
||||
else
|
||||
i2c->ret = viai2c_fifo_irq_xfer(i2c, true);
|
||||
}
|
||||
|
||||
/* All the data has been successfully transferred or error occurred */
|
||||
if (i2c->ret)
|
||||
complete(&i2c->complete);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(viai2c_irq_xfer);
|
||||
|
||||
int viai2c_init(struct platform_device *pdev, struct viai2c **pi2c, int plat)
|
||||
{
|
||||
int err;
|
||||
int irq_flags;
|
||||
struct viai2c *i2c;
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
|
||||
i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL);
|
||||
if (!i2c)
|
||||
@ -225,28 +187,8 @@ int viai2c_init(struct platform_device *pdev, struct viai2c **pi2c, int plat)
|
||||
if (IS_ERR(i2c->base))
|
||||
return PTR_ERR(i2c->base);
|
||||
|
||||
if (plat == VIAI2C_PLAT_WMT) {
|
||||
irq_flags = 0;
|
||||
i2c->irq = irq_of_parse_and_map(np, 0);
|
||||
if (!i2c->irq)
|
||||
return -EINVAL;
|
||||
} else if (plat == VIAI2C_PLAT_ZHAOXIN) {
|
||||
irq_flags = IRQF_SHARED;
|
||||
i2c->irq = platform_get_irq(pdev, 0);
|
||||
if (i2c->irq < 0)
|
||||
return i2c->irq;
|
||||
} else {
|
||||
return dev_err_probe(&pdev->dev, -EINVAL, "wrong platform type\n");
|
||||
}
|
||||
|
||||
i2c->platform = plat;
|
||||
|
||||
err = devm_request_irq(&pdev->dev, i2c->irq, viai2c_isr,
|
||||
irq_flags, pdev->name, i2c);
|
||||
if (err)
|
||||
return dev_err_probe(&pdev->dev, err,
|
||||
"failed to request irq %i\n", i2c->irq);
|
||||
|
||||
i2c->dev = &pdev->dev;
|
||||
init_completion(&i2c->complete);
|
||||
platform_set_drvdata(pdev, i2c);
|
||||
@ -254,3 +196,8 @@ int viai2c_init(struct platform_device *pdev, struct viai2c **pi2c, int plat)
|
||||
*pi2c = i2c;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(viai2c_init);
|
||||
|
||||
MODULE_DESCRIPTION("Via/Wondermedia/Zhaoxin I2C master-mode bus adapter");
|
||||
MODULE_AUTHOR("Tony Prisk <linux@prisktech.co.nz>");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -80,6 +80,6 @@ struct viai2c {
|
||||
int viai2c_wait_bus_not_busy(struct viai2c *i2c);
|
||||
int viai2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num);
|
||||
int viai2c_init(struct platform_device *pdev, struct viai2c **pi2c, int plat);
|
||||
int viai2c_fifo_irq_xfer(struct viai2c *i2c, bool irq);
|
||||
int viai2c_irq_xfer(struct viai2c *i2c);
|
||||
|
||||
#endif
|
||||
|
@ -72,6 +72,32 @@ static int wmt_i2c_reset_hardware(struct viai2c *i2c)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static irqreturn_t wmt_i2c_isr(int irq, void *data)
|
||||
{
|
||||
struct viai2c *i2c = data;
|
||||
u8 status;
|
||||
|
||||
/* save the status and write-clear it */
|
||||
status = readw(i2c->base + VIAI2C_REG_ISR);
|
||||
writew(status, i2c->base + VIAI2C_REG_ISR);
|
||||
|
||||
i2c->ret = 0;
|
||||
if (status & VIAI2C_ISR_NACK_ADDR)
|
||||
i2c->ret = -EIO;
|
||||
|
||||
if (status & VIAI2C_ISR_SCL_TIMEOUT)
|
||||
i2c->ret = -ETIMEDOUT;
|
||||
|
||||
if (!i2c->ret)
|
||||
i2c->ret = viai2c_irq_xfer(i2c);
|
||||
|
||||
/* All the data has been successfully transferred or error occurred */
|
||||
if (i2c->ret)
|
||||
complete(&i2c->complete);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int wmt_i2c_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
@ -84,6 +110,16 @@ static int wmt_i2c_probe(struct platform_device *pdev)
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
i2c->irq = platform_get_irq(pdev, 0);
|
||||
if (i2c->irq < 0)
|
||||
return i2c->irq;
|
||||
|
||||
err = devm_request_irq(&pdev->dev, i2c->irq, wmt_i2c_isr,
|
||||
0, pdev->name, i2c);
|
||||
if (err)
|
||||
return dev_err_probe(&pdev->dev, err,
|
||||
"failed to request irq %i\n", i2c->irq);
|
||||
|
||||
i2c->clk = of_clk_get(np, 0);
|
||||
if (IS_ERR(i2c->clk)) {
|
||||
dev_err(&pdev->dev, "unable to request clock\n");
|
||||
|
@ -49,8 +49,7 @@ struct viai2c_zhaoxin {
|
||||
u16 xfer_len;
|
||||
};
|
||||
|
||||
/* 'irq == true' means in interrupt context */
|
||||
int viai2c_fifo_irq_xfer(struct viai2c *i2c, bool irq)
|
||||
static int viai2c_fifo_xfer(struct viai2c *i2c)
|
||||
{
|
||||
u16 i;
|
||||
u8 tmp;
|
||||
@ -59,17 +58,6 @@ int viai2c_fifo_irq_xfer(struct viai2c *i2c, bool irq)
|
||||
bool read = !!(msg->flags & I2C_M_RD);
|
||||
struct viai2c_zhaoxin *priv = i2c->pltfm_priv;
|
||||
|
||||
if (irq) {
|
||||
/* get the received data */
|
||||
if (read)
|
||||
for (i = 0; i < priv->xfer_len; i++)
|
||||
msg->buf[i2c->xfered_len + i] = ioread8(base + ZXI2C_REG_HRDR);
|
||||
|
||||
i2c->xfered_len += priv->xfer_len;
|
||||
if (i2c->xfered_len == msg->len)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* reset fifo buffer */
|
||||
tmp = ioread8(base + ZXI2C_REG_HCR);
|
||||
iowrite8(tmp | ZXI2C_HCR_RST_FIFO, base + ZXI2C_REG_HCR);
|
||||
@ -92,18 +80,59 @@ int viai2c_fifo_irq_xfer(struct viai2c *i2c, bool irq)
|
||||
iowrite8(tmp, base + VIAI2C_REG_CR);
|
||||
}
|
||||
|
||||
if (irq) {
|
||||
/* continue transmission */
|
||||
tmp = ioread8(base + VIAI2C_REG_CR);
|
||||
iowrite8(tmp |= VIAI2C_CR_CPU_RDY, base + VIAI2C_REG_CR);
|
||||
} else {
|
||||
u16 tcr_val = i2c->tcr;
|
||||
u16 tcr_val = i2c->tcr;
|
||||
|
||||
/* start transmission */
|
||||
tcr_val |= read ? VIAI2C_TCR_READ : 0;
|
||||
writew(tcr_val | msg->addr, base + VIAI2C_REG_TCR);
|
||||
/* start transmission */
|
||||
tcr_val |= read ? VIAI2C_TCR_READ : 0;
|
||||
writew(tcr_val | msg->addr, base + VIAI2C_REG_TCR);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int viai2c_fifo_irq_xfer(struct viai2c *i2c)
|
||||
{
|
||||
u16 i;
|
||||
u8 tmp;
|
||||
struct i2c_msg *msg = i2c->msg;
|
||||
void __iomem *base = i2c->base;
|
||||
bool read = !!(msg->flags & I2C_M_RD);
|
||||
struct viai2c_zhaoxin *priv = i2c->pltfm_priv;
|
||||
|
||||
/* get the received data */
|
||||
if (read)
|
||||
for (i = 0; i < priv->xfer_len; i++)
|
||||
msg->buf[i2c->xfered_len + i] = ioread8(base + ZXI2C_REG_HRDR);
|
||||
|
||||
i2c->xfered_len += priv->xfer_len;
|
||||
if (i2c->xfered_len == msg->len)
|
||||
return 1;
|
||||
|
||||
/* reset fifo buffer */
|
||||
tmp = ioread8(base + ZXI2C_REG_HCR);
|
||||
iowrite8(tmp | ZXI2C_HCR_RST_FIFO, base + ZXI2C_REG_HCR);
|
||||
|
||||
/* set xfer len */
|
||||
priv->xfer_len = min_t(u16, msg->len - i2c->xfered_len, ZXI2C_FIFO_SIZE);
|
||||
if (read) {
|
||||
iowrite8(priv->xfer_len - 1, base + ZXI2C_REG_HRLR);
|
||||
} else {
|
||||
iowrite8(priv->xfer_len - 1, base + ZXI2C_REG_HTLR);
|
||||
/* set write data */
|
||||
for (i = 0; i < priv->xfer_len; i++)
|
||||
iowrite8(msg->buf[i2c->xfered_len + i], base + ZXI2C_REG_HTDR);
|
||||
}
|
||||
|
||||
/* prepare to stop transmission */
|
||||
if (priv->hrv && msg->len == (i2c->xfered_len + priv->xfer_len)) {
|
||||
tmp = ioread8(base + VIAI2C_REG_CR);
|
||||
tmp |= read ? VIAI2C_CR_RX_END : VIAI2C_CR_TX_END;
|
||||
iowrite8(tmp, base + VIAI2C_REG_CR);
|
||||
}
|
||||
|
||||
/* continue transmission */
|
||||
tmp = ioread8(base + VIAI2C_REG_CR);
|
||||
iowrite8(tmp |= VIAI2C_CR_CPU_RDY, base + VIAI2C_REG_CR);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -135,7 +164,7 @@ static int zxi2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int
|
||||
priv->xfer_len = 0;
|
||||
i2c->xfered_len = 0;
|
||||
|
||||
viai2c_fifo_irq_xfer(i2c, 0);
|
||||
viai2c_fifo_xfer(i2c);
|
||||
|
||||
if (!wait_for_completion_timeout(&i2c->complete, VIAI2C_TIMEOUT))
|
||||
return -ETIMEDOUT;
|
||||
@ -228,6 +257,36 @@ static void zxi2c_get_bus_speed(struct viai2c *i2c)
|
||||
dev_info(i2c->dev, "speed mode is %s\n", i2c_freq_mode_string(params[0]));
|
||||
}
|
||||
|
||||
static irqreturn_t zxi2c_isr(int irq, void *data)
|
||||
{
|
||||
struct viai2c *i2c = data;
|
||||
u8 status;
|
||||
|
||||
/* save the status and write-clear it */
|
||||
status = readw(i2c->base + VIAI2C_REG_ISR);
|
||||
if (!status)
|
||||
return IRQ_NONE;
|
||||
|
||||
writew(status, i2c->base + VIAI2C_REG_ISR);
|
||||
|
||||
i2c->ret = 0;
|
||||
if (status & VIAI2C_ISR_NACK_ADDR)
|
||||
i2c->ret = -EIO;
|
||||
|
||||
if (!i2c->ret) {
|
||||
if (i2c->mode == VIAI2C_BYTE_MODE)
|
||||
i2c->ret = viai2c_irq_xfer(i2c);
|
||||
else
|
||||
i2c->ret = viai2c_fifo_irq_xfer(i2c);
|
||||
}
|
||||
|
||||
/* All the data has been successfully transferred or error occurred */
|
||||
if (i2c->ret)
|
||||
complete(&i2c->complete);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int zxi2c_probe(struct platform_device *pdev)
|
||||
{
|
||||
int error;
|
||||
@ -239,6 +298,16 @@ static int zxi2c_probe(struct platform_device *pdev)
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
i2c->irq = platform_get_irq(pdev, 0);
|
||||
if (i2c->irq < 0)
|
||||
return i2c->irq;
|
||||
|
||||
error = devm_request_irq(&pdev->dev, i2c->irq, zxi2c_isr,
|
||||
IRQF_SHARED, pdev->name, i2c);
|
||||
if (error)
|
||||
return dev_err_probe(&pdev->dev, error,
|
||||
"failed to request irq %i\n", i2c->irq);
|
||||
|
||||
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
Loading…
Reference in New Issue
Block a user