diff options
author | Chris Pascoe <c.pascoe@itee.uq.edu.au> | 2007-11-19 02:14:23 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-01-25 16:02:21 -0500 |
commit | 47cc5b78102b4e9993ea1c054b4f077cf7aac7db (patch) | |
tree | 2f4fc9d03c042e1215d56cad7268f1469d80284f /drivers/media/video/tuner-xc2028.c | |
parent | 794604c3efb511b74fb664af72c5dd7046e91075 (diff) |
V4L/DVB (6631): xc2028: eliminate i2c macro side-effects
The I2C macros have side effects and send_seq could cause a return from
a function with a mutex held. Change them to behave like real functions.
Signed-off-by: Chris Pascoe <c.pascoe@itee.uq.edu.au>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/tuner-xc2028.c')
-rw-r--r-- | drivers/media/video/tuner-xc2028.c | 82 |
1 files changed, 46 insertions, 36 deletions
diff --git a/drivers/media/video/tuner-xc2028.c b/drivers/media/video/tuner-xc2028.c index d23b33a1f696..6e23fad0e560 100644 --- a/drivers/media/video/tuner-xc2028.c +++ b/drivers/media/video/tuner-xc2028.c | |||
@@ -83,31 +83,35 @@ struct xc2028_data { | |||
83 | struct mutex lock; | 83 | struct mutex lock; |
84 | }; | 84 | }; |
85 | 85 | ||
86 | #define i2c_send(rc, priv, buf, size) do { \ | 86 | #define i2c_send(priv, buf, size) ({ \ |
87 | rc = tuner_i2c_xfer_send(&priv->i2c_props, buf, size); \ | 87 | int _rc; \ |
88 | if (size != rc) \ | 88 | _rc = tuner_i2c_xfer_send(&priv->i2c_props, buf, size); \ |
89 | tuner_err("i2c output error: rc = %d (should be %d)\n", \ | 89 | if (size != _rc) \ |
90 | rc, (int)size); \ | 90 | tuner_info("i2c output error: rc = %d (should be %d)\n",\ |
91 | } while (0) | 91 | _rc, (int)size); \ |
92 | 92 | _rc; \ | |
93 | #define i2c_rcv(rc, priv, buf, size) do { \ | 93 | }) |
94 | rc = tuner_i2c_xfer_recv(&priv->i2c_props, buf, size); \ | 94 | |
95 | if (size != rc) \ | 95 | #define i2c_rcv(priv, buf, size) ({ \ |
96 | int _rc; \ | ||
97 | _rc = tuner_i2c_xfer_recv(&priv->i2c_props, buf, size); \ | ||
98 | if (size != _rc) \ | ||
96 | tuner_err("i2c input error: rc = %d (should be %d)\n", \ | 99 | tuner_err("i2c input error: rc = %d (should be %d)\n", \ |
97 | rc, (int)size); \ | 100 | _rc, (int)size); \ |
98 | } while (0) | 101 | _rc; \ |
102 | }) | ||
99 | 103 | ||
100 | #define send_seq(priv, data...) do { \ | 104 | #define send_seq(priv, data...) ({ \ |
101 | int rc; \ | ||
102 | static u8 _val[] = data; \ | 105 | static u8 _val[] = data; \ |
106 | int _rc; \ | ||
103 | if (sizeof(_val) != \ | 107 | if (sizeof(_val) != \ |
104 | (rc = tuner_i2c_xfer_send(&priv->i2c_props, \ | 108 | (_rc = tuner_i2c_xfer_send(&priv->i2c_props, \ |
105 | _val, sizeof(_val)))) { \ | 109 | _val, sizeof(_val)))) { \ |
106 | tuner_err("Error on line %d: %d\n", __LINE__, rc); \ | 110 | tuner_err("Error on line %d: %d\n", __LINE__, _rc); \ |
107 | return -EINVAL; \ | 111 | } else \ |
108 | } \ | 112 | msleep(10); \ |
109 | msleep(10); \ | 113 | _rc; \ |
110 | } while (0) | 114 | }) |
111 | 115 | ||
112 | static unsigned int xc2028_get_reg(struct xc2028_data *priv, u16 reg) | 116 | static unsigned int xc2028_get_reg(struct xc2028_data *priv, u16 reg) |
113 | { | 117 | { |
@@ -119,11 +123,11 @@ static unsigned int xc2028_get_reg(struct xc2028_data *priv, u16 reg) | |||
119 | buf[0] = reg>>8; | 123 | buf[0] = reg>>8; |
120 | buf[1] = (unsigned char) reg; | 124 | buf[1] = (unsigned char) reg; |
121 | 125 | ||
122 | i2c_send(rc, priv, buf, 2); | 126 | rc = i2c_send(priv, buf, 2); |
123 | if (rc < 0) | 127 | if (rc < 0) |
124 | return rc; | 128 | return rc; |
125 | 129 | ||
126 | i2c_rcv(rc, priv, buf, 2); | 130 | rc = i2c_rcv(priv, buf, 2); |
127 | if (rc < 0) | 131 | if (rc < 0) |
128 | return rc; | 132 | return rc; |
129 | 133 | ||
@@ -505,7 +509,7 @@ static int load_firmware(struct dvb_frontend *fe, unsigned int type, | |||
505 | 509 | ||
506 | memcpy(buf + 1, p, len); | 510 | memcpy(buf + 1, p, len); |
507 | 511 | ||
508 | i2c_send(rc, priv, buf, len + 1); | 512 | rc = i2c_send(priv, buf, len + 1); |
509 | if (rc < 0) { | 513 | if (rc < 0) { |
510 | tuner_err("%d returned from send\n", rc); | 514 | tuner_err("%d returned from send\n", rc); |
511 | return -EINVAL; | 515 | return -EINVAL; |
@@ -541,15 +545,20 @@ static int load_scode(struct dvb_frontend *fe, unsigned int type, | |||
541 | if ((priv->firm[pos].size != 12 * 16) || (scode >= 16)) | 545 | if ((priv->firm[pos].size != 12 * 16) || (scode >= 16)) |
542 | return -EINVAL; | 546 | return -EINVAL; |
543 | 547 | ||
544 | if (priv->version < 0x0202) { | 548 | if (priv->version < 0x0202) |
545 | send_seq(priv, {0x20, 0x00, 0x00, 0x00}); | 549 | rc = send_seq(priv, {0x20, 0x00, 0x00, 0x00}); |
546 | } else { | 550 | else |
547 | send_seq(priv, {0xa0, 0x00, 0x00, 0x00}); | 551 | rc = send_seq(priv, {0xa0, 0x00, 0x00, 0x00}); |
548 | } | 552 | if (rc < 0) |
553 | return -EIO; | ||
549 | 554 | ||
550 | i2c_send(rc, priv, p + 12 * scode, 12); | 555 | rc = i2c_send(priv, p + 12 * scode, 12); |
556 | if (rc < 0) | ||
557 | return -EIO; | ||
551 | 558 | ||
552 | send_seq(priv, {0x00, 0x8c}); | 559 | rc = send_seq(priv, {0x00, 0x8c}); |
560 | if (rc < 0) | ||
561 | return -EIO; | ||
553 | 562 | ||
554 | return 0; | 563 | return 0; |
555 | } | 564 | } |
@@ -766,11 +775,12 @@ static int generic_set_tv_freq(struct dvb_frontend *fe, u32 freq /* in Hz */ , | |||
766 | 775 | ||
767 | /* CMD= Set frequency */ | 776 | /* CMD= Set frequency */ |
768 | 777 | ||
769 | if (priv->version < 0x0202) { | 778 | if (priv->version < 0x0202) |
770 | send_seq(priv, {0x00, 0x02, 0x00, 0x00}); | 779 | rc = send_seq(priv, {0x00, 0x02, 0x00, 0x00}); |
771 | } else { | 780 | else |
772 | send_seq(priv, {0x80, 0x02, 0x00, 0x00}); | 781 | rc = send_seq(priv, {0x80, 0x02, 0x00, 0x00}); |
773 | } | 782 | if (rc < 0) |
783 | goto ret; | ||
774 | 784 | ||
775 | rc = priv->tuner_callback(priv->video_dev, XC2028_RESET_CLK, 1); | 785 | rc = priv->tuner_callback(priv->video_dev, XC2028_RESET_CLK, 1); |
776 | if (rc < 0) | 786 | if (rc < 0) |
@@ -784,7 +794,7 @@ static int generic_set_tv_freq(struct dvb_frontend *fe, u32 freq /* in Hz */ , | |||
784 | buf[3] = 0xff & (div); | 794 | buf[3] = 0xff & (div); |
785 | buf[4] = 0; | 795 | buf[4] = 0; |
786 | 796 | ||
787 | i2c_send(rc, priv, buf, sizeof(buf)); | 797 | rc = i2c_send(priv, buf, sizeof(buf)); |
788 | if (rc < 0) | 798 | if (rc < 0) |
789 | goto ret; | 799 | goto ret; |
790 | msleep(100); | 800 | msleep(100); |