Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

i2c-parport-light: Don't register a platform device resource

The i2c-parport-light driver isn't a real platform driver, so it
should not instantiate platform devices with resources. The resource
management system can't cope with colliding resources, and we are
likely to create such a colliding resource.

So, better just try to grab the I/O ports we need right at module
initialization time, and bail out if we can't. It has the added
benefit that the module will no longer load if it isn't going to work,
which is definitely more user-friendly.

Signed-off-by: Jean Delvare <khali@linux-fr.org>

authored by

Jean Delvare and committed by
Jean Delvare
9def2556 67a37308

+8 -31
+8 -31
drivers/i2c/busses/i2c-parport-light.c
··· 123 123 static int __devinit i2c_parport_probe(struct platform_device *pdev) 124 124 { 125 125 int err; 126 - struct resource *res; 127 - 128 - res = platform_get_resource(pdev, IORESOURCE_IO, 0); 129 - if (!request_region(res->start, res->end - res->start + 1, DRVNAME)) 130 - return -EBUSY; 131 126 132 127 /* Reset hardware to a sane state (SCL and SDA high) */ 133 128 parport_setsda(NULL, 1); ··· 133 138 134 139 parport_adapter.dev.parent = &pdev->dev; 135 140 err = i2c_bit_add_bus(&parport_adapter); 136 - if (err) { 141 + if (err) 137 142 dev_err(&pdev->dev, "Unable to register with I2C\n"); 138 - goto exit_region; 139 - } 140 - return 0; 141 - 142 - exit_region: 143 - release_region(res->start, res->end - res->start + 1); 144 143 return err; 145 144 } 146 145 147 146 static int __devexit i2c_parport_remove(struct platform_device *pdev) 148 147 { 149 - struct resource *res; 150 - 151 148 i2c_del_adapter(&parport_adapter); 152 149 153 150 /* Un-init if needed (power off...) */ 154 151 if (adapter_parm[type].init.val) 155 152 line_set(0, &adapter_parm[type].init); 156 153 157 - res = platform_get_resource(pdev, IORESOURCE_IO, 0); 158 - release_region(res->start, res->end - res->start + 1); 159 154 return 0; 160 155 } 161 156 ··· 160 175 161 176 static int __init i2c_parport_device_add(u16 address) 162 177 { 163 - struct resource res = { 164 - .start = address, 165 - .end = address + 2, 166 - .name = DRVNAME, 167 - .flags = IORESOURCE_IO, 168 - }; 169 178 int err; 170 179 171 180 pdev = platform_device_alloc(DRVNAME, -1); ··· 167 188 err = -ENOMEM; 168 189 printk(KERN_ERR DRVNAME ": Device allocation failed\n"); 169 190 goto exit; 170 - } 171 - 172 - err = platform_device_add_resources(pdev, &res, 1); 173 - if (err) { 174 - printk(KERN_ERR DRVNAME ": Device resource addition failed " 175 - "(%d)\n", err); 176 - goto exit_device_put; 177 191 } 178 192 179 193 err = platform_device_add(pdev); ··· 203 231 base = DEFAULT_BASE; 204 232 } 205 233 234 + if (!request_region(base, 3, DRVNAME)) 235 + return -EBUSY; 236 + 206 237 if (!adapter_parm[type].getscl.val) 207 238 parport_algo_data.getscl = NULL; 208 239 209 240 /* Sets global pdev as a side effect */ 210 241 err = i2c_parport_device_add(base); 211 242 if (err) 212 - goto exit; 243 + goto exit_release; 213 244 214 245 err = platform_driver_register(&i2c_parport_driver); 215 246 if (err) ··· 222 247 223 248 exit_device: 224 249 platform_device_unregister(pdev); 225 - exit: 250 + exit_release: 251 + release_region(base, 3); 226 252 return err; 227 253 } 228 254 ··· 231 255 { 232 256 platform_driver_unregister(&i2c_parport_driver); 233 257 platform_device_unregister(pdev); 258 + release_region(base, 3); 234 259 } 235 260 236 261 MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");