When compiling the LG stock kernel from source I get an "Initialization from incompatible pointer type" error on the following line:
.detect = mmc_detect
found within this declaration:
static const struct mmc_bus_ops mmc_ops = {
.awake = mmc_awake,
.sleep = mmc_sleep,
.remove = mmc_remove,
.detect = mmc_detect,
.suspend = NULL,
.resume = NULL,
.power_restore = mmc_power_restore,
.alive = mmc_alive,
.change_bus_speed = mmc_change_bus_speed,
};
mmc_bus_ops is declared like this:
struct mmc_bus_ops {
int (*awake)(struct mmc_host *);
int (*sleep)(struct mmc_host *);
void (*remove)(struct mmc_host *);
#ifdef CONFIG_MACH_LGE
int (*detect)(struct mmc_host *);
#else
void (*detect)(struct mmc_host *);
#endif
int (*suspend)(struct mmc_host *);
int (*resume)(struct mmc_host *);
int (*power_save)(struct mmc_host *);
int (*power_restore)(struct mmc_host *);
int (*alive)(struct mmc_host *);
int (*change_bus_speed)(struct mmc_host *, unsigned long *);
};
and mmc_detect like this:
static int mmc_detect(struct mmc_host *host)
{
int err;
BUG_ON(!host);
BUG_ON(!host->card);
mmc_rpm_hold(host, &host->card->dev);
mmc_claim_host(host);
/*
* Just check if our card has been removed.
*/
err = _mmc_detect_card_removed(host);
mmc_release_host(host);
/*
* if detect fails, the device would be removed anyway;
* the rpm framework would mark the device state suspended.
*/
if (!err)
mmc_rpm_release(host, &host->card->dev);
if (err) {
mmc_remove(host);
mmc_claim_host(host);
mmc_detach_bus(host);
mmc_power_off(host);
mmc_release_host(host);
}
return 0;
}
My guess is that the problem here is that mmc_bus_ops.detect is declared as a pointer, but mmc_detect as a normal int. However, as far as I can tell this is also true for mmc_bus_ops.awake and mmc_awake, but that doesn't create any errors. The question is how to fix this and how come I get these errors in the stock kernel? If LG can compile the kernel in this state, why do I have to edit everything first? Any help and explanation is greatly appreciated!
void (*detect)(struct mmc_host *)
is a pointer to a function declared as void func( struct mmc_host* arg)
. Notice the void
return type.
int mmc_detect(struct mmc_host *host)
has an int
return type and is therefore incompatible.
Since mmc_detect
only ever returns 0, and hence the return value is irrelevant, the pointer assignment may be logically acceptable, but may break the compiled code.
If LG can compile this code, then maybe they are using some other compiler flags, allowing warnings to be issued instead of errors. See for example -pedantic-errors for gcc; there are a bunch of other options to set to more or less strictly enforce or forbid certain code structures.