summaryrefslogtreecommitdiff
path: root/drivers/mfd
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/88pm800.c12
-rw-r--r--drivers/mfd/88pm805.c10
-rw-r--r--drivers/mfd/88pm80x.c2
-rw-r--r--drivers/mfd/88pm860x-core.c104
-rw-r--r--drivers/mfd/Kconfig17
-rw-r--r--drivers/mfd/Makefile4
-rw-r--r--drivers/mfd/ab3100-core.c13
-rw-r--r--drivers/mfd/ab8500-core.c73
-rw-r--r--drivers/mfd/ab8500-debugfs.c6
-rw-r--r--drivers/mfd/ab8500-gpadc.c6
-rw-r--r--drivers/mfd/ab8500-sysctrl.c6
-rw-r--r--drivers/mfd/adp5520.c6
-rw-r--r--drivers/mfd/arizona-core.c20
-rw-r--r--drivers/mfd/arizona-i2c.c6
-rw-r--r--drivers/mfd/arizona-irq.c1
-rw-r--r--drivers/mfd/arizona-spi.c6
-rw-r--r--drivers/mfd/asic3.c4
-rw-r--r--drivers/mfd/cs5535-mfd.c12
-rw-r--r--drivers/mfd/da903x.c10
-rw-r--r--drivers/mfd/da9052-core.c4
-rw-r--r--drivers/mfd/da9052-i2c.c6
-rw-r--r--drivers/mfd/da9052-spi.c6
-rw-r--r--drivers/mfd/da9055-core.c4
-rw-r--r--drivers/mfd/da9055-i2c.c6
-rw-r--r--drivers/mfd/davinci_voicecodec.c4
-rw-r--r--drivers/mfd/db8500-prcmu.c100
-rw-r--r--drivers/mfd/ezx-pcap.c8
-rw-r--r--drivers/mfd/htc-i2cpld.c12
-rw-r--r--drivers/mfd/intel_msic.c10
-rw-r--r--drivers/mfd/janz-cmodio.c10
-rw-r--r--drivers/mfd/jz4740-adc.c6
-rw-r--r--drivers/mfd/lm3533-core.c18
-rw-r--r--drivers/mfd/lp8788.c4
-rw-r--r--drivers/mfd/lpc_ich.c20
-rw-r--r--drivers/mfd/lpc_sch.c6
-rw-r--r--drivers/mfd/max77686.c2
-rw-r--r--drivers/mfd/max8907.c4
-rw-r--r--drivers/mfd/max8925-core.c58
-rw-r--r--drivers/mfd/max8925-i2c.c6
-rw-r--r--drivers/mfd/max8997.c73
-rw-r--r--drivers/mfd/mc13xxx-i2c.c4
-rw-r--r--drivers/mfd/mc13xxx-spi.c4
-rw-r--r--drivers/mfd/menelaus.c2
-rw-r--r--drivers/mfd/omap-usb-host.c9
-rw-r--r--drivers/mfd/omap-usb-tll.c8
-rw-r--r--drivers/mfd/omap-usb.h2
-rw-r--r--drivers/mfd/palmas.c6
-rw-r--r--drivers/mfd/pcf50633-adc.c6
-rw-r--r--drivers/mfd/pcf50633-core.c6
-rw-r--r--drivers/mfd/pm8921-core.c8
-rw-r--r--drivers/mfd/pm8xxx-irq.c4
-rw-r--r--drivers/mfd/rc5t583.c6
-rw-r--r--drivers/mfd/rdc321x-southbridge.c6
-rw-r--r--drivers/mfd/rtl8411.c251
-rw-r--r--drivers/mfd/rts5209.c223
-rw-r--r--drivers/mfd/rts5229.c205
-rw-r--r--drivers/mfd/rtsx_pcr.c1251
-rw-r--r--drivers/mfd/rtsx_pcr.h32
-rw-r--r--drivers/mfd/sm501.c16
-rw-r--r--drivers/mfd/sta2x11-mfd.c20
-rw-r--r--drivers/mfd/stmpe-i2c.c6
-rw-r--r--drivers/mfd/stmpe-spi.c6
-rw-r--r--drivers/mfd/stmpe.c2
-rw-r--r--drivers/mfd/syscon.c6
-rw-r--r--drivers/mfd/tc3589x.c8
-rw-r--r--drivers/mfd/tc6387xb.c6
-rw-r--r--drivers/mfd/tc6393xb.c12
-rw-r--r--drivers/mfd/ti-ssp.c6
-rw-r--r--drivers/mfd/timberdale.c64
-rw-r--r--drivers/mfd/tps6105x.c8
-rw-r--r--drivers/mfd/tps65090.c8
-rw-r--r--drivers/mfd/tps65217.c6
-rw-r--r--drivers/mfd/tps6586x.c86
-rw-r--r--drivers/mfd/tps65910.c10
-rw-r--r--drivers/mfd/tps65911-comparator.c6
-rw-r--r--drivers/mfd/tps65912-spi.c6
-rw-r--r--drivers/mfd/twl-core.c4
-rw-r--r--drivers/mfd/twl4030-audio.c6
-rw-r--r--drivers/mfd/twl4030-irq.c3
-rw-r--r--drivers/mfd/twl4030-madc.c4
-rw-r--r--drivers/mfd/twl4030-power.c20
-rw-r--r--drivers/mfd/vexpress-config.c277
-rw-r--r--drivers/mfd/vexpress-sysreg.c475
-rw-r--r--drivers/mfd/vx855.c6
-rw-r--r--drivers/mfd/wl1273-core.c4
-rw-r--r--drivers/mfd/wm5102-tables.c522
-rw-r--r--drivers/mfd/wm831x-spi.c6
-rw-r--r--drivers/mfd/wm8994-core.c51
88 files changed, 3353 insertions, 1025 deletions
diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c
index ce229ea933d1..391e23e6a647 100644
--- a/drivers/mfd/88pm800.c
+++ b/drivers/mfd/88pm800.c
@@ -248,7 +248,7 @@ static const struct regmap_irq pm800_irqs[] = {
},
};
-static int __devinit device_gpadc_init(struct pm80x_chip *chip,
+static int device_gpadc_init(struct pm80x_chip *chip,
struct pm80x_platform_data *pdata)
{
struct pm80x_subchip *subchip = chip->subchip;
@@ -315,7 +315,7 @@ out:
return ret;
}
-static int __devinit device_irq_init_800(struct pm80x_chip *chip)
+static int device_irq_init_800(struct pm80x_chip *chip)
{
struct regmap *map = chip->regmap;
unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
@@ -415,7 +415,7 @@ static void pm800_pages_exit(struct pm80x_chip *chip)
}
}
-static int __devinit device_800_init(struct pm80x_chip *chip,
+static int device_800_init(struct pm80x_chip *chip,
struct pm80x_platform_data *pdata)
{
int ret, pmic_id;
@@ -499,7 +499,7 @@ out:
return ret;
}
-static int __devinit pm800_probe(struct i2c_client *client,
+static int pm800_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int ret = 0;
@@ -554,7 +554,7 @@ out_init:
return ret;
}
-static int __devexit pm800_remove(struct i2c_client *client)
+static int pm800_remove(struct i2c_client *client)
{
struct pm80x_chip *chip = i2c_get_clientdata(client);
@@ -576,7 +576,7 @@ static struct i2c_driver pm800_driver = {
.pm = &pm80x_pm_ops,
},
.probe = pm800_probe,
- .remove = __devexit_p(pm800_remove),
+ .remove = pm800_remove,
.id_table = pm80x_id_table,
};
diff --git a/drivers/mfd/88pm805.c b/drivers/mfd/88pm805.c
index c20a31136f04..e671230be2b1 100644
--- a/drivers/mfd/88pm805.c
+++ b/drivers/mfd/88pm805.c
@@ -135,7 +135,7 @@ static struct regmap_irq pm805_irqs[] = {
},
};
-static int __devinit device_irq_init_805(struct pm80x_chip *chip)
+static int device_irq_init_805(struct pm80x_chip *chip)
{
struct regmap *map = chip->regmap;
unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
@@ -189,7 +189,7 @@ static struct regmap_irq_chip pm805_irq_chip = {
.ack_base = PM805_INT_STATUS1,
};
-static int __devinit device_805_init(struct pm80x_chip *chip)
+static int device_805_init(struct pm80x_chip *chip)
{
int ret = 0;
unsigned int val;
@@ -232,7 +232,7 @@ out_irq_init:
return ret;
}
-static int __devinit pm805_probe(struct i2c_client *client,
+static int pm805_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int ret = 0;
@@ -262,7 +262,7 @@ out_init:
return ret;
}
-static int __devexit pm805_remove(struct i2c_client *client)
+static int pm805_remove(struct i2c_client *client)
{
struct pm80x_chip *chip = i2c_get_clientdata(client);
@@ -281,7 +281,7 @@ static struct i2c_driver pm805_driver = {
.pm = &pm80x_pm_ops,
},
.probe = pm805_probe,
- .remove = __devexit_p(pm805_remove),
+ .remove = pm805_remove,
.id_table = pm80x_id_table,
};
diff --git a/drivers/mfd/88pm80x.c b/drivers/mfd/88pm80x.c
index cd0bf527d764..1adb355d86d1 100644
--- a/drivers/mfd/88pm80x.c
+++ b/drivers/mfd/88pm80x.c
@@ -31,7 +31,7 @@ const struct regmap_config pm80x_regmap_config = {
};
EXPORT_SYMBOL_GPL(pm80x_regmap_config);
-int __devinit pm80x_init(struct i2c_client *client,
+int pm80x_init(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct pm80x_chip *chip;
diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c
index 8fa86edf70d4..893fc1ba6ead 100644
--- a/drivers/mfd/88pm860x-core.c
+++ b/drivers/mfd/88pm860x-core.c
@@ -28,111 +28,111 @@
#define INT_STATUS_NUM 3
-static struct resource bk0_resources[] __devinitdata = {
+static struct resource bk0_resources[] = {
{2, 2, "duty cycle", IORESOURCE_REG, },
{3, 3, "always on", IORESOURCE_REG, },
{3, 3, "current", IORESOURCE_REG, },
};
-static struct resource bk1_resources[] __devinitdata = {
+static struct resource bk1_resources[] = {
{4, 4, "duty cycle", IORESOURCE_REG, },
{5, 5, "always on", IORESOURCE_REG, },
{5, 5, "current", IORESOURCE_REG, },
};
-static struct resource bk2_resources[] __devinitdata = {
+static struct resource bk2_resources[] = {
{6, 6, "duty cycle", IORESOURCE_REG, },
{7, 7, "always on", IORESOURCE_REG, },
{5, 5, "current", IORESOURCE_REG, },
};
-static struct resource led0_resources[] __devinitdata = {
+static struct resource led0_resources[] = {
/* RGB1 Red LED */
{0xd, 0xd, "control", IORESOURCE_REG, },
{0xc, 0xc, "blink", IORESOURCE_REG, },
};
-static struct resource led1_resources[] __devinitdata = {
+static struct resource led1_resources[] = {
/* RGB1 Green LED */
{0xe, 0xe, "control", IORESOURCE_REG, },
{0xc, 0xc, "blink", IORESOURCE_REG, },
};
-static struct resource led2_resources[] __devinitdata = {
+static struct resource led2_resources[] = {
/* RGB1 Blue LED */
{0xf, 0xf, "control", IORESOURCE_REG, },
{0xc, 0xc, "blink", IORESOURCE_REG, },
};
-static struct resource led3_resources[] __devinitdata = {
+static struct resource led3_resources[] = {
/* RGB2 Red LED */
{0x9, 0x9, "control", IORESOURCE_REG, },
{0x8, 0x8, "blink", IORESOURCE_REG, },
};
-static struct resource led4_resources[] __devinitdata = {
+static struct resource led4_resources[] = {
/* RGB2 Green LED */
{0xa, 0xa, "control", IORESOURCE_REG, },
{0x8, 0x8, "blink", IORESOURCE_REG, },
};
-static struct resource led5_resources[] __devinitdata = {
+static struct resource led5_resources[] = {
/* RGB2 Blue LED */
{0xb, 0xb, "control", IORESOURCE_REG, },
{0x8, 0x8, "blink", IORESOURCE_REG, },
};
-static struct resource buck1_resources[] __devinitdata = {
+static struct resource buck1_resources[] = {
{0x24, 0x24, "buck set", IORESOURCE_REG, },
};
-static struct resource buck2_resources[] __devinitdata = {
+static struct resource buck2_resources[] = {
{0x25, 0x25, "buck set", IORESOURCE_REG, },
};
-static struct resource buck3_resources[] __devinitdata = {
+static struct resource buck3_resources[] = {
{0x26, 0x26, "buck set", IORESOURCE_REG, },
};
-static struct resource ldo1_resources[] __devinitdata = {
+static struct resource ldo1_resources[] = {
{0x10, 0x10, "ldo set", IORESOURCE_REG, },
};
-static struct resource ldo2_resources[] __devinitdata = {
+static struct resource ldo2_resources[] = {
{0x11, 0x11, "ldo set", IORESOURCE_REG, },
};
-static struct resource ldo3_resources[] __devinitdata = {
+static struct resource ldo3_resources[] = {
{0x12, 0x12, "ldo set", IORESOURCE_REG, },
};
-static struct resource ldo4_resources[] __devinitdata = {
+static struct resource ldo4_resources[] = {
{0x13, 0x13, "ldo set", IORESOURCE_REG, },
};
-static struct resource ldo5_resources[] __devinitdata = {
+static struct resource ldo5_resources[] = {
{0x14, 0x14, "ldo set", IORESOURCE_REG, },
};
-static struct resource ldo6_resources[] __devinitdata = {
+static struct resource ldo6_resources[] = {
{0x15, 0x15, "ldo set", IORESOURCE_REG, },
};
-static struct resource ldo7_resources[] __devinitdata = {
+static struct resource ldo7_resources[] = {
{0x16, 0x16, "ldo set", IORESOURCE_REG, },
};
-static struct resource ldo8_resources[] __devinitdata = {
+static struct resource ldo8_resources[] = {
{0x17, 0x17, "ldo set", IORESOURCE_REG, },
};
-static struct resource ldo9_resources[] __devinitdata = {
+static struct resource ldo9_resources[] = {
{0x18, 0x18, "ldo set", IORESOURCE_REG, },
};
-static struct resource ldo10_resources[] __devinitdata = {
+static struct resource ldo10_resources[] = {
{0x19, 0x19, "ldo set", IORESOURCE_REG, },
};
-static struct resource ldo12_resources[] __devinitdata = {
+static struct resource ldo12_resources[] = {
{0x1a, 0x1a, "ldo set", IORESOURCE_REG, },
};
-static struct resource ldo_vibrator_resources[] __devinitdata = {
+static struct resource ldo_vibrator_resources[] = {
{0x28, 0x28, "ldo set", IORESOURCE_REG, },
};
-static struct resource ldo14_resources[] __devinitdata = {
+static struct resource ldo14_resources[] = {
{0x1b, 0x1b, "ldo set", IORESOURCE_REG, },
};
-static struct resource touch_resources[] __devinitdata = {
+static struct resource touch_resources[] = {
{PM8607_IRQ_PEN, PM8607_IRQ_PEN, "touch", IORESOURCE_IRQ,},
};
-static struct resource onkey_resources[] __devinitdata = {
+static struct resource onkey_resources[] = {
{PM8607_IRQ_ONKEY, PM8607_IRQ_ONKEY, "onkey", IORESOURCE_IRQ,},
};
-static struct resource codec_resources[] __devinitdata = {
+static struct resource codec_resources[] = {
/* Headset microphone insertion or removal */
{PM8607_IRQ_MICIN, PM8607_IRQ_MICIN, "micin", IORESOURCE_IRQ,},
/* Hook-switch press or release */
@@ -143,12 +143,12 @@ static struct resource codec_resources[] __devinitdata = {
{PM8607_IRQ_AUDIO_SHORT, PM8607_IRQ_AUDIO_SHORT, "audio-short", IORESOURCE_IRQ,},
};
-static struct resource battery_resources[] __devinitdata = {
+static struct resource battery_resources[] = {
{PM8607_IRQ_CC, PM8607_IRQ_CC, "columb counter", IORESOURCE_IRQ,},
{PM8607_IRQ_BAT, PM8607_IRQ_BAT, "battery", IORESOURCE_IRQ,},
};
-static struct resource charger_resources[] __devinitdata = {
+static struct resource charger_resources[] = {
{PM8607_IRQ_CHG, PM8607_IRQ_CHG, "charger detect", IORESOURCE_IRQ,},
{PM8607_IRQ_CHG_DONE, PM8607_IRQ_CHG_DONE, "charging done", IORESOURCE_IRQ,},
{PM8607_IRQ_CHG_FAIL, PM8607_IRQ_CHG_FAIL, "charging timeout", IORESOURCE_IRQ,},
@@ -158,11 +158,11 @@ static struct resource charger_resources[] __devinitdata = {
{PM8607_IRQ_VCHG, PM8607_IRQ_VCHG, "vchg voltage", IORESOURCE_IRQ,},
};
-static struct resource rtc_resources[] __devinitdata = {
+static struct resource rtc_resources[] = {
{PM8607_IRQ_RTC, PM8607_IRQ_RTC, "rtc", IORESOURCE_IRQ,},
};
-static struct mfd_cell bk_devs[] __devinitdata = {
+static struct mfd_cell bk_devs[] = {
{
.name = "88pm860x-backlight",
.id = 0,
@@ -181,7 +181,7 @@ static struct mfd_cell bk_devs[] __devinitdata = {
},
};
-static struct mfd_cell led_devs[] __devinitdata = {
+static struct mfd_cell led_devs[] = {
{
.name = "88pm860x-led",
.id = 0,
@@ -215,7 +215,7 @@ static struct mfd_cell led_devs[] __devinitdata = {
},
};
-static struct mfd_cell reg_devs[] __devinitdata = {
+static struct mfd_cell reg_devs[] = {
{
.name = "88pm860x-regulator",
.id = 0,
@@ -565,7 +565,7 @@ static struct irq_domain_ops pm860x_irq_domain_ops = {
.xlate = irq_domain_xlate_onetwocell,
};
-static int __devinit device_irq_init(struct pm860x_chip *chip,
+static int device_irq_init(struct pm860x_chip *chip,
struct pm860x_platform_data *pdata)
{
struct i2c_client *i2c = (chip->id == CHIP_PM8607) ? chip->client \
@@ -730,7 +730,7 @@ out:
}
EXPORT_SYMBOL(pm8606_osc_disable);
-static void __devinit device_osc_init(struct i2c_client *i2c)
+static void device_osc_init(struct i2c_client *i2c)
{
struct pm860x_chip *chip = i2c_get_clientdata(i2c);
@@ -745,7 +745,7 @@ static void __devinit device_osc_init(struct i2c_client *i2c)
chip->osc_status = PM8606_REF_GP_OSC_OFF;
}
-static void __devinit device_bk_init(struct pm860x_chip *chip,
+static void device_bk_init(struct pm860x_chip *chip,
struct pm860x_platform_data *pdata)
{
int ret, i;
@@ -765,7 +765,7 @@ static void __devinit device_bk_init(struct pm860x_chip *chip,
dev_err(chip->dev, "Failed to add backlight subdev\n");
}
-static void __devinit device_led_init(struct pm860x_chip *chip,
+static void device_led_init(struct pm860x_chip *chip,
struct pm860x_platform_data *pdata)
{
int ret, i;
@@ -787,7 +787,7 @@ static void __devinit device_led_init(struct pm860x_chip *chip,
}
}
-static void __devinit device_regulator_init(struct pm860x_chip *chip,
+static void device_regulator_init(struct pm860x_chip *chip,
struct pm860x_platform_data *pdata)
{
int ret;
@@ -866,7 +866,7 @@ static void __devinit device_regulator_init(struct pm860x_chip *chip,
}
}
-static void __devinit device_rtc_init(struct pm860x_chip *chip,
+static void device_rtc_init(struct pm860x_chip *chip,
struct pm860x_platform_data *pdata)
{
int ret;
@@ -885,7 +885,7 @@ static void __devinit device_rtc_init(struct pm860x_chip *chip,
dev_err(chip->dev, "Failed to add rtc subdev\n");
}
-static void __devinit device_touch_init(struct pm860x_chip *chip,
+static void device_touch_init(struct pm860x_chip *chip,
struct pm860x_platform_data *pdata)
{
int ret;
@@ -904,7 +904,7 @@ static void __devinit device_touch_init(struct pm860x_chip *chip,
dev_err(chip->dev, "Failed to add touch subdev\n");
}
-static void __devinit device_power_init(struct pm860x_chip *chip,
+static void device_power_init(struct pm860x_chip *chip,
struct pm860x_platform_data *pdata)
{
int ret;
@@ -951,7 +951,7 @@ static void __devinit device_power_init(struct pm860x_chip *chip,
}
}
-static void __devinit device_onkey_init(struct pm860x_chip *chip,
+static void device_onkey_init(struct pm860x_chip *chip,
struct pm860x_platform_data *pdata)
{
int ret;
@@ -965,7 +965,7 @@ static void __devinit device_onkey_init(struct pm860x_chip *chip,
dev_err(chip->dev, "Failed to add onkey subdev\n");
}
-static void __devinit device_codec_init(struct pm860x_chip *chip,
+static void device_codec_init(struct pm860x_chip *chip,
struct pm860x_platform_data *pdata)
{
int ret;
@@ -979,7 +979,7 @@ static void __devinit device_codec_init(struct pm860x_chip *chip,
dev_err(chip->dev, "Failed to add codec subdev\n");
}
-static void __devinit device_8607_init(struct pm860x_chip *chip,
+static void device_8607_init(struct pm860x_chip *chip,
struct i2c_client *i2c,
struct pm860x_platform_data *pdata)
{
@@ -1040,7 +1040,7 @@ out:
return;
}
-static void __devinit device_8606_init(struct pm860x_chip *chip,
+static void device_8606_init(struct pm860x_chip *chip,
struct i2c_client *i2c,
struct pm860x_platform_data *pdata)
{
@@ -1049,7 +1049,7 @@ static void __devinit device_8606_init(struct pm860x_chip *chip,
device_led_init(chip, pdata);
}
-static int __devinit pm860x_device_init(struct pm860x_chip *chip,
+static int pm860x_device_init(struct pm860x_chip *chip,
struct pm860x_platform_data *pdata)
{
chip->core_irq = 0;
@@ -1077,7 +1077,7 @@ static int __devinit pm860x_device_init(struct pm860x_chip *chip,
return 0;
}
-static void __devexit pm860x_device_exit(struct pm860x_chip *chip)
+static void pm860x_device_exit(struct pm860x_chip *chip)
{
device_irq_exit(chip);
mfd_remove_devices(chip->dev);
@@ -1109,7 +1109,7 @@ static struct regmap_config pm860x_regmap_config = {
.val_bits = 8,
};
-static int __devinit pm860x_dt_init(struct device_node *np,
+static int pm860x_dt_init(struct device_node *np,
struct device *dev,
struct pm860x_platform_data *pdata)
{
@@ -1127,7 +1127,7 @@ static int __devinit pm860x_dt_init(struct device_node *np,
return 0;
}
-static int __devinit pm860x_probe(struct i2c_client *client,
+static int pm860x_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct pm860x_platform_data *pdata = client->dev.platform_data;
@@ -1200,7 +1200,7 @@ err:
return ret;
}
-static int __devexit pm860x_remove(struct i2c_client *client)
+static int pm860x_remove(struct i2c_client *client)
{
struct pm860x_chip *chip = i2c_get_clientdata(client);
@@ -1258,7 +1258,7 @@ static struct i2c_driver pm860x_driver = {
.of_match_table = of_match_ptr(pm860x_dt_ids),
},
.probe = pm860x_probe,
- .remove = __devexit_p(pm860x_remove),
+ .remove = pm860x_remove,
.id_table = pm860x_id_table,
};
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index acab3ef8a310..b63987c6ed20 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -63,6 +63,16 @@ config MFD_SM501_GPIO
lines on the SM501. The platform data is used to supply the
base number for the first GPIO line to register.
+config MFD_RTSX_PCI
+ tristate "Support for Realtek PCI-E card reader"
+ depends on PCI
+ select MFD_CORE
+ help
+ This supports for Realtek PCI-Express card reader including rts5209,
+ rts5229, rtl8411, etc. Realtek card reader supports access to many
+ types of memory cards, such as Memory Stick, Memory Stick Pro,
+ Secure Digital and MultiMediaCard.
+
config MFD_ASIC3
bool "Support for Compaq ASIC3"
depends on GENERIC_HARDIRQS && GPIOLIB && ARM
@@ -201,7 +211,6 @@ config MFD_TPS6586X
depends on I2C=y && GENERIC_HARDIRQS
select MFD_CORE
select REGMAP_I2C
- depends on REGULATOR
help
If you say yes here you get support for the TPS6586X series of
Power Management chips.
@@ -1070,3 +1079,9 @@ config MCP_UCB1200_TS
depends on MCP_UCB1200 && INPUT
endmenu
+
+config VEXPRESS_CONFIG
+ bool
+ help
+ Platform configuration infrastructure for the ARM Ltd.
+ Versatile Express.
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index d8ccb630ddb0..69f260ae0225 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -9,6 +9,9 @@ obj-$(CONFIG_MFD_88PM805) += 88pm805.o 88pm80x.o
obj-$(CONFIG_MFD_SM501) += sm501.o
obj-$(CONFIG_MFD_ASIC3) += asic3.o tmio_core.o
+rtsx_pci-objs := rtsx_pcr.o rts5209.o rts5229.o rtl8411.o
+obj-$(CONFIG_MFD_RTSX_PCI) += rtsx_pci.o
+
obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o
obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o
obj-$(CONFIG_HTC_I2CPLD) += htc-i2cpld.o
@@ -138,3 +141,4 @@ obj-$(CONFIG_MFD_RC5T583) += rc5t583.o rc5t583-irq.o
obj-$(CONFIG_MFD_SEC_CORE) += sec-core.o sec-irq.o
obj-$(CONFIG_MFD_SYSCON) += syscon.o
obj-$(CONFIG_MFD_LM3533) += lm3533-core.o lm3533-ctrlbank.o
+obj-$(CONFIG_VEXPRESS_CONFIG) += vexpress-config.o vexpress-sysreg.o
diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c
index 2b3dde571a50..2ec7725f4a08 100644
--- a/drivers/mfd/ab3100-core.c
+++ b/drivers/mfd/ab3100-core.c
@@ -661,8 +661,7 @@ struct ab3100_init_setting {
u8 setting;
};
-static const struct ab3100_init_setting __devinitconst
-ab3100_init_settings[] = {
+static const struct ab3100_init_setting ab3100_init_settings[] = {
{
.abreg = AB3100_MCA,
.setting = 0x01
@@ -708,7 +707,7 @@ ab3100_init_settings[] = {
},
};
-static int __devinit ab3100_setup(struct ab3100 *ab3100)
+static int ab3100_setup(struct ab3100 *ab3100)
{
int err = 0;
int i;
@@ -803,7 +802,7 @@ struct ab_family_id {
char *name;
};
-static const struct ab_family_id ids[] __devinitconst = {
+static const struct ab_family_id ids[] = {
/* AB3100 */
{
.id = 0xc0,
@@ -857,7 +856,7 @@ static const struct ab_family_id ids[] __devinitconst = {
},
};
-static int __devinit ab3100_probe(struct i2c_client *client,
+static int ab3100_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct ab3100 *ab3100;
@@ -962,7 +961,7 @@ static int __devinit ab3100_probe(struct i2c_client *client,
return err;
}
-static int __devexit ab3100_remove(struct i2c_client *client)
+static int ab3100_remove(struct i2c_client *client)
{
struct ab3100 *ab3100 = i2c_get_clientdata(client);
@@ -986,7 +985,7 @@ static struct i2c_driver ab3100_driver = {
},
.id_table = ab3100_id,
.probe = ab3100_probe,
- .remove = __devexit_p(ab3100_remove),
+ .remove = ab3100_remove,
};
static int __init ab3100_i2c_init(void)
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c
index 1667c77b5cde..59da1650fb81 100644
--- a/drivers/mfd/ab8500-core.c
+++ b/drivers/mfd/ab8500-core.c
@@ -565,15 +565,10 @@ static int ab8500_irq_init(struct ab8500 *ab8500, struct device_node *np)
else
num_irqs = AB8500_NR_IRQS;
- if (ab8500->irq_base) {
- ab8500->domain = irq_domain_add_legacy(
- NULL, num_irqs, ab8500->irq_base,
- 0, &ab8500_irq_ops, ab8500);
- }
- else {
- ab8500->domain = irq_domain_add_linear(
- np, num_irqs, &ab8500_irq_ops, ab8500);
- }
+ /* If ->irq_base is zero this will give a linear mapping */
+ ab8500->domain = irq_domain_add_simple(NULL,
+ num_irqs, ab8500->irq_base,
+ &ab8500_irq_ops, ab8500);
if (!ab8500->domain) {
dev_err(ab8500->dev, "Failed to create irqdomain\n");
@@ -623,7 +618,7 @@ static struct resource __devinitdata ab9540_gpio_resources[] = {
}
};
-static struct resource __devinitdata ab8500_gpadc_resources[] = {
+static struct resource ab8500_gpadc_resources[] = {
{
.name = "HW_CONV_END",
.start = AB8500_INT_GP_HW_ADC_CONV_END,
@@ -638,7 +633,7 @@ static struct resource __devinitdata ab8500_gpadc_resources[] = {
},
};
-static struct resource __devinitdata ab8500_rtc_resources[] = {
+static struct resource ab8500_rtc_resources[] = {
{
.name = "60S",
.start = AB8500_INT_RTC_60S,
@@ -653,7 +648,7 @@ static struct resource __devinitdata ab8500_rtc_resources[] = {
},
};
-static struct resource __devinitdata ab8500_poweronkey_db_resources[] = {
+static struct resource ab8500_poweronkey_db_resources[] = {
{
.name = "ONKEY_DBF",
.start = AB8500_INT_PON_KEY1DB_F,
@@ -668,7 +663,7 @@ static struct resource __devinitdata ab8500_poweronkey_db_resources[] = {
},
};
-static struct resource __devinitdata ab8500_av_acc_detect_resources[] = {
+static struct resource ab8500_av_acc_detect_resources[] = {
{
.name = "ACC_DETECT_1DB_F",
.start = AB8500_INT_ACC_DETECT_1DB_F,
@@ -707,7 +702,7 @@ static struct resource __devinitdata ab8500_av_acc_detect_resources[] = {
},
};
-static struct resource __devinitdata ab8500_charger_resources[] = {
+static struct resource ab8500_charger_resources[] = {
{
.name = "MAIN_CH_UNPLUG_DET",
.start = AB8500_INT_MAIN_CH_UNPLUG_DET,
@@ -788,7 +783,7 @@ static struct resource __devinitdata ab8500_charger_resources[] = {
},
};
-static struct resource __devinitdata ab8500_btemp_resources[] = {
+static struct resource ab8500_btemp_resources[] = {
{
.name = "BAT_CTRL_INDB",
.start = AB8500_INT_BAT_CTRL_INDB,
@@ -821,7 +816,7 @@ static struct resource __devinitdata ab8500_btemp_resources[] = {
},
};
-static struct resource __devinitdata ab8500_fg_resources[] = {
+static struct resource ab8500_fg_resources[] = {
{
.name = "NCONV_ACCU",
.start = AB8500_INT_CCN_CONV_ACC,
@@ -860,10 +855,10 @@ static struct resource __devinitdata ab8500_fg_resources[] = {
},
};
-static struct resource __devinitdata ab8500_chargalg_resources[] = {};
+static struct resource ab8500_chargalg_resources[] = {};
#ifdef CONFIG_DEBUG_FS
-static struct resource __devinitdata ab8500_debug_resources[] = {
+static struct resource ab8500_debug_resources[] = {
{
.name = "IRQ_FIRST",
.start = AB8500_INT_MAIN_EXT_CH_NOT_OK,
@@ -879,7 +874,7 @@ static struct resource __devinitdata ab8500_debug_resources[] = {
};
#endif
-static struct resource __devinitdata ab8500_usb_resources[] = {
+static struct resource ab8500_usb_resources[] = {
{
.name = "ID_WAKEUP_R",
.start = AB8500_INT_ID_WAKEUP_R,
@@ -924,7 +919,7 @@ static struct resource __devinitdata ab8500_usb_resources[] = {
},
};
-static struct resource __devinitdata ab8505_iddet_resources[] = {
+static struct resource ab8505_iddet_resources[] = {
{
.name = "KeyDeglitch",
.start = AB8505_INT_KEYDEGLITCH,
@@ -957,7 +952,7 @@ static struct resource __devinitdata ab8505_iddet_resources[] = {
},
};
-static struct resource __devinitdata ab8500_temp_resources[] = {
+static struct resource ab8500_temp_resources[] = {
{
.name = "AB8500_TEMP_WARM",
.start = AB8500_INT_TEMP_WARM,
@@ -966,7 +961,7 @@ static struct resource __devinitdata ab8500_temp_resources[] = {
},
};
-static struct mfd_cell __devinitdata abx500_common_devs[] = {
+static struct mfd_cell abx500_common_devs[] = {
#ifdef CONFIG_DEBUG_FS
{
.name = "ab8500-debug",
@@ -1038,30 +1033,50 @@ static struct mfd_cell __devinitdata abx500_common_devs[] = {
},
};
-static struct mfd_cell __devinitdata ab8500_bm_devs[] = {
+static struct mfd_cell ab8500_bm_devs[] = {
{
.name = "ab8500-charger",
+ .of_compatible = "stericsson,ab8500-charger",
.num_resources = ARRAY_SIZE(ab8500_charger_resources),
.resources = ab8500_charger_resources,
+#ifndef CONFIG_OF
+ .platform_data = &ab8500_bm_data,
+ .pdata_size = sizeof(ab8500_bm_data),
+#endif
},
{
.name = "ab8500-btemp",
+ .of_compatible = "stericsson,ab8500-btemp",
.num_resources = ARRAY_SIZE(ab8500_btemp_resources),
.resources = ab8500_btemp_resources,
+#ifndef CONFIG_OF
+ .platform_data = &ab8500_bm_data,
+ .pdata_size = sizeof(ab8500_bm_data),
+#endif
},
{
.name = "ab8500-fg",
+ .of_compatible = "stericsson,ab8500-fg",
.num_resources = ARRAY_SIZE(ab8500_fg_resources),
.resources = ab8500_fg_resources,
+#ifndef CONFIG_OF
+ .platform_data = &ab8500_bm_data,
+ .pdata_size = sizeof(ab8500_bm_data),
+#endif
},
{
.name = "ab8500-chargalg",
+ .of_compatible = "stericsson,ab8500-chargalg",
.num_resources = ARRAY_SIZE(ab8500_chargalg_resources),
.resources = ab8500_chargalg_resources,
+#ifndef CONFIG_OF
+ .platform_data = &ab8500_bm_data,
+ .pdata_size = sizeof(ab8500_bm_data),
+#endif
},
};
-static struct mfd_cell __devinitdata ab8500_devs[] = {
+static struct mfd_cell ab8500_devs[] = {
{
.name = "ab8500-gpio",
.of_compatible = "stericsson,ab8500-gpio",
@@ -1080,7 +1095,7 @@ static struct mfd_cell __devinitdata ab8500_devs[] = {
},
};
-static struct mfd_cell __devinitdata ab9540_devs[] = {
+static struct mfd_cell ab9540_devs[] = {
{
.name = "ab8500-gpio",
.num_resources = ARRAY_SIZE(ab9540_gpio_resources),
@@ -1097,7 +1112,7 @@ static struct mfd_cell __devinitdata ab9540_devs[] = {
};
/* Device list common to ab9540 and ab8505 */
-static struct mfd_cell __devinitdata ab9540_ab8505_devs[] = {
+static struct mfd_cell ab9540_ab8505_devs[] = {
{
.name = "ab-iddet",
.num_resources = ARRAY_SIZE(ab8505_iddet_resources),
@@ -1248,7 +1263,7 @@ static struct attribute_group ab9540_attr_group = {
.attrs = ab9540_sysfs_entries,
};
-static int __devinit ab8500_probe(struct platform_device *pdev)
+static int ab8500_probe(struct platform_device *pdev)
{
static char *switch_off_status[] = {
"Swoff bit programming",
@@ -1473,7 +1488,7 @@ out_free_ab8500:
return ret;
}
-static int __devexit ab8500_remove(struct platform_device *pdev)
+static int ab8500_remove(struct platform_device *pdev)
{
struct ab8500 *ab8500 = platform_get_drvdata(pdev);
@@ -1506,7 +1521,7 @@ static struct platform_driver ab8500_core_driver = {
.owner = THIS_MODULE,
},
.probe = ab8500_probe,
- .remove = __devexit_p(ab8500_remove),
+ .remove = ab8500_remove,
.id_table = ab8500_id,
};
diff --git a/drivers/mfd/ab8500-debugfs.c b/drivers/mfd/ab8500-debugfs.c
index c4cb806978ac..5a8e707bc038 100644
--- a/drivers/mfd/ab8500-debugfs.c
+++ b/drivers/mfd/ab8500-debugfs.c
@@ -552,7 +552,7 @@ static struct dentry *ab8500_bank_file;
static struct dentry *ab8500_address_file;
static struct dentry *ab8500_val_file;
-static int __devinit ab8500_debug_probe(struct platform_device *plf)
+static int ab8500_debug_probe(struct platform_device *plf)
{
debug_bank = AB8500_MISC;
debug_address = AB8500_REV_REG & 0x00FF;
@@ -597,7 +597,7 @@ exit_no_debugfs:
return -ENOMEM;
}
-static int __devexit ab8500_debug_remove(struct platform_device *plf)
+static int ab8500_debug_remove(struct platform_device *plf)
{
debugfs_remove(ab8500_val_file);
debugfs_remove(ab8500_address_file);
@@ -614,7 +614,7 @@ static struct platform_driver ab8500_debug_driver = {
.owner = THIS_MODULE,
},
.probe = ab8500_debug_probe,
- .remove = __devexit_p(ab8500_debug_remove)
+ .remove = ab8500_debug_remove
};
static int __init ab8500_debug_init(void)
diff --git a/drivers/mfd/ab8500-gpadc.c b/drivers/mfd/ab8500-gpadc.c
index 29d72a259c85..3fb1f40d6389 100644
--- a/drivers/mfd/ab8500-gpadc.c
+++ b/drivers/mfd/ab8500-gpadc.c
@@ -571,7 +571,7 @@ static void ab8500_gpadc_read_calibration_data(struct ab8500_gpadc *gpadc)
gpadc->cal_data[ADC_INPUT_VBAT].offset);
}
-static int __devinit ab8500_gpadc_probe(struct platform_device *pdev)
+static int ab8500_gpadc_probe(struct platform_device *pdev)
{
int ret = 0;
struct ab8500_gpadc *gpadc;
@@ -634,7 +634,7 @@ fail:
return ret;
}
-static int __devexit ab8500_gpadc_remove(struct platform_device *pdev)
+static int ab8500_gpadc_remove(struct platform_device *pdev)
{
struct ab8500_gpadc *gpadc = platform_get_drvdata(pdev);
@@ -651,7 +651,7 @@ static int __devexit ab8500_gpadc_remove(struct platform_device *pdev)
static struct platform_driver ab8500_gpadc_driver = {
.probe = ab8500_gpadc_probe,
- .remove = __devexit_p(ab8500_gpadc_remove),
+ .remove = ab8500_gpadc_remove,
.driver = {
.name = "ab8500-gpadc",
.owner = THIS_MODULE,
diff --git a/drivers/mfd/ab8500-sysctrl.c b/drivers/mfd/ab8500-sysctrl.c
index c28d4eb1eff0..8a33b2c7eead 100644
--- a/drivers/mfd/ab8500-sysctrl.c
+++ b/drivers/mfd/ab8500-sysctrl.c
@@ -49,13 +49,13 @@ int ab8500_sysctrl_write(u16 reg, u8 mask, u8 value)
(u8)(reg & 0xFF), mask, value);
}
-static int __devinit ab8500_sysctrl_probe(struct platform_device *pdev)
+static int ab8500_sysctrl_probe(struct platform_device *pdev)
{
sysctrl_dev = &pdev->dev;
return 0;
}
-static int __devexit ab8500_sysctrl_remove(struct platform_device *pdev)
+static int ab8500_sysctrl_remove(struct platform_device *pdev)
{
sysctrl_dev = NULL;
return 0;
@@ -67,7 +67,7 @@ static struct platform_driver ab8500_sysctrl_driver = {
.owner = THIS_MODULE,
},
.probe = ab8500_sysctrl_probe,
- .remove = __devexit_p(ab8500_sysctrl_remove),
+ .remove = ab8500_sysctrl_remove,
};
static int __init ab8500_sysctrl_init(void)
diff --git a/drivers/mfd/adp5520.c b/drivers/mfd/adp5520.c
index ea8b9475731d..210dd038bb5a 100644
--- a/drivers/mfd/adp5520.c
+++ b/drivers/mfd/adp5520.c
@@ -203,7 +203,7 @@ static int adp5520_remove_subdevs(struct adp5520_chip *chip)
return device_for_each_child(chip->dev, NULL, __remove_subdev);
}
-static int __devinit adp5520_probe(struct i2c_client *client,
+static int adp5520_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct adp5520_platform_data *pdata = client->dev.platform_data;
@@ -307,7 +307,7 @@ out_free_chip:
return ret;
}
-static int __devexit adp5520_remove(struct i2c_client *client)
+static int adp5520_remove(struct i2c_client *client)
{
struct adp5520_chip *chip = dev_get_drvdata(&client->dev);
@@ -356,7 +356,7 @@ static struct i2c_driver adp5520_driver = {
.pm = &adp5520_pm,
},
.probe = adp5520_probe,
- .remove = __devexit_p(adp5520_remove),
+ .remove = adp5520_remove,
.id_table = adp5520_id,
};
diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c
index 1b48f2094806..c784f4602a74 100644
--- a/drivers/mfd/arizona-core.c
+++ b/drivers/mfd/arizona-core.c
@@ -98,9 +98,9 @@ static irqreturn_t arizona_underclocked(int irq, void *data)
if (val & ARIZONA_AIF3_UNDERCLOCKED_STS)
dev_err(arizona->dev, "AIF3 underclocked\n");
- if (val & ARIZONA_AIF3_UNDERCLOCKED_STS)
- dev_err(arizona->dev, "AIF3 underclocked\n");
if (val & ARIZONA_AIF2_UNDERCLOCKED_STS)
+ dev_err(arizona->dev, "AIF2 underclocked\n");
+ if (val & ARIZONA_AIF1_UNDERCLOCKED_STS)
dev_err(arizona->dev, "AIF1 underclocked\n");
if (val & ARIZONA_ISRC2_UNDERCLOCKED_STS)
dev_err(arizona->dev, "ISRC2 underclocked\n");
@@ -272,6 +272,7 @@ static struct mfd_cell early_devs[] = {
static struct mfd_cell wm5102_devs[] = {
{ .name = "arizona-extcon" },
{ .name = "arizona-gpio" },
+ { .name = "arizona-haptics" },
{ .name = "arizona-micsupp" },
{ .name = "arizona-pwm" },
{ .name = "wm5102-codec" },
@@ -280,12 +281,13 @@ static struct mfd_cell wm5102_devs[] = {
static struct mfd_cell wm5110_devs[] = {
{ .name = "arizona-extcon" },
{ .name = "arizona-gpio" },
+ { .name = "arizona-haptics" },
{ .name = "arizona-micsupp" },
{ .name = "arizona-pwm" },
{ .name = "wm5110-codec" },
};
-int __devinit arizona_dev_init(struct arizona *arizona)
+int arizona_dev_init(struct arizona *arizona)
{
struct device *dev = arizona->dev;
const char *type_name;
@@ -415,11 +417,19 @@ int __devinit arizona_dev_init(struct arizona *arizona)
/* If we have a /RESET GPIO we'll already be reset */
if (!arizona->pdata.reset) {
+ regcache_mark_dirty(arizona->regmap);
+
ret = regmap_write(arizona->regmap, ARIZONA_SOFTWARE_RESET, 0);
if (ret != 0) {
dev_err(dev, "Failed to reset device: %d\n", ret);
goto err_reset;
}
+
+ ret = regcache_sync(arizona->regmap);
+ if (ret != 0) {
+ dev_err(dev, "Failed to sync device: %d\n", ret);
+ goto err_reset;
+ }
}
ret = arizona_wait_for_boot(arizona);
@@ -520,7 +530,7 @@ int __devinit arizona_dev_init(struct arizona *arizona)
break;
case WM5110:
ret = mfd_add_devices(arizona->dev, -1, wm5110_devs,
- ARRAY_SIZE(wm5102_devs), NULL, 0, NULL);
+ ARRAY_SIZE(wm5110_devs), NULL, 0, NULL);
break;
}
@@ -553,7 +563,7 @@ err_early:
}
EXPORT_SYMBOL_GPL(arizona_dev_init);
-int __devexit arizona_dev_exit(struct arizona *arizona)
+int arizona_dev_exit(struct arizona *arizona)
{
mfd_remove_devices(arizona->dev);
arizona_free_irq(arizona, ARIZONA_IRQ_UNDERCLOCKED, arizona);
diff --git a/drivers/mfd/arizona-i2c.c b/drivers/mfd/arizona-i2c.c
index 570c4b438086..44a1bb969841 100644
--- a/drivers/mfd/arizona-i2c.c
+++ b/drivers/mfd/arizona-i2c.c
@@ -22,7 +22,7 @@
#include "arizona.h"
-static __devinit int arizona_i2c_probe(struct i2c_client *i2c,
+static int arizona_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct arizona *arizona;
@@ -65,7 +65,7 @@ static __devinit int arizona_i2c_probe(struct i2c_client *i2c,
return arizona_dev_init(arizona);
}
-static int __devexit arizona_i2c_remove(struct i2c_client *i2c)
+static int arizona_i2c_remove(struct i2c_client *i2c)
{
struct arizona *arizona = dev_get_drvdata(&i2c->dev);
arizona_dev_exit(arizona);
@@ -86,7 +86,7 @@ static struct i2c_driver arizona_i2c_driver = {
.pm = &arizona_pm_ops,
},
.probe = arizona_i2c_probe,
- .remove = __devexit_p(arizona_i2c_remove),
+ .remove = arizona_i2c_remove,
.id_table = arizona_i2c_id,
};
diff --git a/drivers/mfd/arizona-irq.c b/drivers/mfd/arizona-irq.c
index ef0f2d001df2..b1b009177405 100644
--- a/drivers/mfd/arizona-irq.c
+++ b/drivers/mfd/arizona-irq.c
@@ -178,6 +178,7 @@ int arizona_irq_init(struct arizona *arizona)
switch (arizona->rev) {
case 0:
+ case 1:
ctrlif_error = false;
break;
default:
diff --git a/drivers/mfd/arizona-spi.c b/drivers/mfd/arizona-spi.c
index df2e5a8bee28..1b9fdd698b03 100644
--- a/drivers/mfd/arizona-spi.c
+++ b/drivers/mfd/arizona-spi.c
@@ -22,7 +22,7 @@
#include "arizona.h"
-static int __devinit arizona_spi_probe(struct spi_device *spi)
+static int arizona_spi_probe(struct spi_device *spi)
{
const struct spi_device_id *id = spi_get_device_id(spi);
struct arizona *arizona;
@@ -65,7 +65,7 @@ static int __devinit arizona_spi_probe(struct spi_device *spi)
return arizona_dev_init(arizona);
}
-static int __devexit arizona_spi_remove(struct spi_device *spi)
+static int arizona_spi_remove(struct spi_device *spi)
{
struct arizona *arizona = dev_get_drvdata(&spi->dev);
arizona_dev_exit(arizona);
@@ -86,7 +86,7 @@ static struct spi_driver arizona_spi_driver = {
.pm = &arizona_pm_ops,
},
.probe = arizona_spi_probe,
- .remove = __devexit_p(arizona_spi_remove),
+ .remove = arizona_spi_remove,
.id_table = arizona_spi_ids,
};
diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c
index 62f0883a7630..1b15986c01e1 100644
--- a/drivers/mfd/asic3.c
+++ b/drivers/mfd/asic3.c
@@ -1039,7 +1039,7 @@ static int __init asic3_probe(struct platform_device *pdev)
return ret;
}
-static int __devexit asic3_remove(struct platform_device *pdev)
+static int asic3_remove(struct platform_device *pdev)
{
int ret;
struct asic3 *asic = platform_get_drvdata(pdev);
@@ -1071,7 +1071,7 @@ static struct platform_driver asic3_device_driver = {
.driver = {
.name = "asic3",
},
- .remove = __devexit_p(asic3_remove),
+ .remove = asic3_remove,
.shutdown = asic3_shutdown,
};
diff --git a/drivers/mfd/cs5535-mfd.c b/drivers/mfd/cs5535-mfd.c
index 2b282133c725..2e4752a9220a 100644
--- a/drivers/mfd/cs5535-mfd.c
+++ b/drivers/mfd/cs5535-mfd.c
@@ -71,9 +71,9 @@ static int cs5535_mfd_res_disable(struct platform_device *pdev)
return 0;
}
-static __devinitdata struct resource cs5535_mfd_resources[NR_BARS];
+static struct resource cs5535_mfd_resources[NR_BARS];
-static __devinitdata struct mfd_cell cs5535_mfd_cells[] = {
+static struct mfd_cell cs5535_mfd_cells[] = {
{
.id = SMB_BAR,
.name = "cs5535-smb",
@@ -113,7 +113,7 @@ static __devinitdata struct mfd_cell cs5535_mfd_cells[] = {
};
#ifdef CONFIG_OLPC
-static void __devinit cs5535_clone_olpc_cells(void)
+static void cs5535_clone_olpc_cells(void)
{
const char *acpi_clones[] = { "olpc-xo1-pm-acpi", "olpc-xo1-sci-acpi" };
@@ -126,7 +126,7 @@ static void __devinit cs5535_clone_olpc_cells(void)
static void cs5535_clone_olpc_cells(void) { }
#endif
-static int __devinit cs5535_mfd_probe(struct pci_dev *pdev,
+static int cs5535_mfd_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
int err, i;
@@ -166,7 +166,7 @@ err_disable:
return err;
}
-static void __devexit cs5535_mfd_remove(struct pci_dev *pdev)
+static void cs5535_mfd_remove(struct pci_dev *pdev)
{
mfd_remove_devices(&pdev->dev);
pci_disable_device(pdev);
@@ -183,7 +183,7 @@ static struct pci_driver cs5535_mfd_driver = {
.name = DRV_NAME,
.id_table = cs5535_mfd_pci_tbl,
.probe = cs5535_mfd_probe,
- .remove = __devexit_p(cs5535_mfd_remove),
+ .remove = cs5535_mfd_remove,
};
module_pci_driver(cs5535_mfd_driver);
diff --git a/drivers/mfd/da903x.c b/drivers/mfd/da903x.c
index 1924b857a0fb..05176cd2862b 100644
--- a/drivers/mfd/da903x.c
+++ b/drivers/mfd/da903x.c
@@ -246,7 +246,7 @@ int da903x_query_status(struct device *dev, unsigned int sbits)
}
EXPORT_SYMBOL(da903x_query_status);
-static int __devinit da9030_init_chip(struct da903x_chip *chip)
+static int da9030_init_chip(struct da903x_chip *chip)
{
uint8_t chip_id;
int err;
@@ -459,7 +459,7 @@ static int da903x_remove_subdevs(struct da903x_chip *chip)
return device_for_each_child(chip->dev, NULL, __remove_subdev);
}
-static int __devinit da903x_add_subdevs(struct da903x_chip *chip,
+static int da903x_add_subdevs(struct da903x_chip *chip,
struct da903x_platform_data *pdata)
{
struct da903x_subdev_info *subdev;
@@ -491,7 +491,7 @@ failed:
return ret;
}
-static int __devinit da903x_probe(struct i2c_client *client,
+static int da903x_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct da903x_platform_data *pdata = client->dev.platform_data;
@@ -544,7 +544,7 @@ out_free_chip:
return ret;
}
-static int __devexit da903x_remove(struct i2c_client *client)
+static int da903x_remove(struct i2c_client *client)
{
struct da903x_chip *chip = i2c_get_clientdata(client);
@@ -560,7 +560,7 @@ static struct i2c_driver da903x_driver = {
.owner = THIS_MODULE,
},
.probe = da903x_probe,
- .remove = __devexit_p(da903x_remove),
+ .remove = da903x_remove,
.id_table = da903x_id_table,
};
diff --git a/drivers/mfd/da9052-core.c b/drivers/mfd/da9052-core.c
index a0a62b24621b..689b747416af 100644
--- a/drivers/mfd/da9052-core.c
+++ b/drivers/mfd/da9052-core.c
@@ -515,7 +515,7 @@ static struct resource da9052_tsi_resources[] = {
},
};
-static struct mfd_cell __devinitdata da9052_subdev_info[] = {
+static struct mfd_cell da9052_subdev_info[] = {
{
.name = "da9052-regulator",
.id = 1,
@@ -769,7 +769,7 @@ struct regmap_config da9052_regmap_config = {
};
EXPORT_SYMBOL_GPL(da9052_regmap_config);
-int __devinit da9052_device_init(struct da9052 *da9052, u8 chip_id)
+int da9052_device_init(struct da9052 *da9052, u8 chip_id)
{
struct da9052_pdata *pdata = da9052->dev->platform_data;
int ret;
diff --git a/drivers/mfd/da9052-i2c.c b/drivers/mfd/da9052-i2c.c
index 352c58b5a90d..ac74a4d1daea 100644
--- a/drivers/mfd/da9052-i2c.c
+++ b/drivers/mfd/da9052-i2c.c
@@ -64,7 +64,7 @@ static const struct of_device_id dialog_dt_ids[] = {
};
#endif
-static int __devinit da9052_i2c_probe(struct i2c_client *client,
+static int da9052_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct da9052 *da9052;
@@ -121,7 +121,7 @@ static int __devinit da9052_i2c_probe(struct i2c_client *client,
return 0;
}
-static int __devexit da9052_i2c_remove(struct i2c_client *client)
+static int da9052_i2c_remove(struct i2c_client *client)
{
struct da9052 *da9052 = i2c_get_clientdata(client);
@@ -131,7 +131,7 @@ static int __devexit da9052_i2c_remove(struct i2c_client *client)
static struct i2c_driver da9052_i2c_driver = {
.probe = da9052_i2c_probe,
- .remove = __devexit_p(da9052_i2c_remove),
+ .remove = da9052_i2c_remove,
.id_table = da9052_i2c_id,
.driver = {
.name = "da9052",
diff --git a/drivers/mfd/da9052-spi.c b/drivers/mfd/da9052-spi.c
index dbeadc5a6436..61d63b93576c 100644
--- a/drivers/mfd/da9052-spi.c
+++ b/drivers/mfd/da9052-spi.c
@@ -21,7 +21,7 @@
#include <linux/mfd/da9052/da9052.h>
-static int __devinit da9052_spi_probe(struct spi_device *spi)
+static int da9052_spi_probe(struct spi_device *spi)
{
int ret;
const struct spi_device_id *id = spi_get_device_id(spi);
@@ -58,7 +58,7 @@ static int __devinit da9052_spi_probe(struct spi_device *spi)
return 0;
}
-static int __devexit da9052_spi_remove(struct spi_device *spi)
+static int da9052_spi_remove(struct spi_device *spi)
{
struct da9052 *da9052 = dev_get_drvdata(&spi->dev);
@@ -76,7 +76,7 @@ static struct spi_device_id da9052_spi_id[] = {
static struct spi_driver da9052_spi_driver = {
.probe = da9052_spi_probe,
- .remove = __devexit_p(da9052_spi_remove),
+ .remove = da9052_spi_remove,
.id_table = da9052_spi_id,
.driver = {
.name = "da9052",
diff --git a/drivers/mfd/da9055-core.c b/drivers/mfd/da9055-core.c
index ff6c77f392bd..f56a1a9f7777 100644
--- a/drivers/mfd/da9055-core.c
+++ b/drivers/mfd/da9055-core.c
@@ -377,7 +377,7 @@ static struct regmap_irq_chip da9055_regmap_irq_chip = {
.num_irqs = ARRAY_SIZE(da9055_irqs),
};
-int __devinit da9055_device_init(struct da9055 *da9055)
+int da9055_device_init(struct da9055 *da9055)
{
struct da9055_pdata *pdata = da9055->dev->platform_data;
int ret;
@@ -412,7 +412,7 @@ err:
return ret;
}
-void __devexit da9055_device_exit(struct da9055 *da9055)
+void da9055_device_exit(struct da9055 *da9055)
{
regmap_del_irq_chip(da9055->chip_irq, da9055->irq_data);
mfd_remove_devices(da9055->dev);
diff --git a/drivers/mfd/da9055-i2c.c b/drivers/mfd/da9055-i2c.c
index 88f6dca53bac..607387ffe8ca 100644
--- a/drivers/mfd/da9055-i2c.c
+++ b/drivers/mfd/da9055-i2c.c
@@ -18,7 +18,7 @@
#include <linux/mfd/da9055/core.h>
-static int __devinit da9055_i2c_probe(struct i2c_client *i2c,
+static int da9055_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct da9055 *da9055;
@@ -44,7 +44,7 @@ static int __devinit da9055_i2c_probe(struct i2c_client *i2c,
return da9055_device_init(da9055);
}
-static int __devexit da9055_i2c_remove(struct i2c_client *i2c)
+static int da9055_i2c_remove(struct i2c_client *i2c)
{
struct da9055 *da9055 = i2c_get_clientdata(i2c);
@@ -60,7 +60,7 @@ static struct i2c_device_id da9055_i2c_id[] = {
static struct i2c_driver da9055_i2c_driver = {
.probe = da9055_i2c_probe,
- .remove = __devexit_p(da9055_i2c_remove),
+ .remove = da9055_i2c_remove,
.id_table = da9055_i2c_id,
.driver = {
.name = "da9055",
diff --git a/drivers/mfd/davinci_voicecodec.c b/drivers/mfd/davinci_voicecodec.c
index 45e83a68641b..c0bcc872af4e 100644
--- a/drivers/mfd/davinci_voicecodec.c
+++ b/drivers/mfd/davinci_voicecodec.c
@@ -151,7 +151,7 @@ fail1:
return ret;
}
-static int __devexit davinci_vc_remove(struct platform_device *pdev)
+static int davinci_vc_remove(struct platform_device *pdev)
{
struct davinci_vc *davinci_vc = platform_get_drvdata(pdev);
@@ -174,7 +174,7 @@ static struct platform_driver davinci_vc_driver = {
.name = "davinci_voicecodec",
.owner = THIS_MODULE,
},
- .remove = __devexit_p(davinci_vc_remove),
+ .remove = davinci_vc_remove,
};
static int __init davinci_vc_init(void)
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c
index 00b8b0f3dfb6..29710565a08f 100644
--- a/drivers/mfd/db8500-prcmu.c
+++ b/drivers/mfd/db8500-prcmu.c
@@ -31,6 +31,7 @@
#include <linux/mfd/abx500/ab8500.h>
#include <linux/regulator/db8500-prcmu.h>
#include <linux/regulator/machine.h>
+#include <linux/cpufreq.h>
#include <asm/hardware/gic.h>
#include <mach/hardware.h>
#include <mach/irqs.h>
@@ -420,9 +421,6 @@ static struct {
static atomic_t ac_wake_req_state = ATOMIC_INIT(0);
-/* Functions definition */
-static void compute_armss_rate(void);
-
/* Spinlocks */
static DEFINE_SPINLOCK(prcmu_lock);
static DEFINE_SPINLOCK(clkout_lock);
@@ -1019,7 +1017,6 @@ int db8500_prcmu_set_arm_opp(u8 opp)
(mb1_transfer.ack.arm_opp != opp))
r = -EIO;
- compute_armss_rate();
mutex_unlock(&mb1_transfer.lock);
return r;
@@ -1169,12 +1166,12 @@ int db8500_prcmu_get_ape_opp(void)
}
/**
- * prcmu_request_ape_opp_100_voltage - Request APE OPP 100% voltage
+ * db8500_prcmu_request_ape_opp_100_voltage - Request APE OPP 100% voltage
* @enable: true to request the higher voltage, false to drop a request.
*
* Calls to this function to enable and disable requests must be balanced.
*/
-int prcmu_request_ape_opp_100_voltage(bool enable)
+int db8500_prcmu_request_ape_opp_100_voltage(bool enable)
{
int r = 0;
u8 header;
@@ -1669,13 +1666,8 @@ static unsigned long clock_rate(u8 clock)
else
return 0;
}
-static unsigned long latest_armss_rate;
-static unsigned long armss_rate(void)
-{
- return latest_armss_rate;
-}
-static void compute_armss_rate(void)
+static unsigned long armss_rate(void)
{
u32 r;
unsigned long rate;
@@ -1700,7 +1692,7 @@ static void compute_armss_rate(void)
rate = pll_rate(PRCM_PLLARM_FREQ, ROOT_CLOCK_RATE, PLL_DIV);
}
- latest_armss_rate = rate;
+ return rate;
}
static unsigned long dsiclk_rate(u8 n)
@@ -1820,6 +1812,35 @@ static long round_clock_rate(u8 clock, unsigned long rate)
return rounded_rate;
}
+/* CPU FREQ table, may be changed due to if MAX_OPP is supported. */
+static struct cpufreq_frequency_table db8500_cpufreq_table[] = {
+ { .frequency = 200000, .index = ARM_EXTCLK,},
+ { .frequency = 400000, .index = ARM_50_OPP,},
+ { .frequency = 800000, .index = ARM_100_OPP,},
+ { .frequency = CPUFREQ_TABLE_END,}, /* To be used for MAX_OPP. */
+ { .frequency = CPUFREQ_TABLE_END,},
+};
+
+static long round_armss_rate(unsigned long rate)
+{
+ long freq = 0;
+ int i = 0;
+
+ /* cpufreq table frequencies is in KHz. */
+ rate = rate / 1000;
+
+ /* Find the corresponding arm opp from the cpufreq table. */
+ while (db8500_cpufreq_table[i].frequency != CPUFREQ_TABLE_END) {
+ freq = db8500_cpufreq_table[i].frequency;
+ if (freq == rate)
+ break;
+ i++;
+ }
+
+ /* Return the last valid value, even if a match was not found. */
+ return freq * 1000;
+}
+
#define MIN_PLL_VCO_RATE 600000000ULL
#define MAX_PLL_VCO_RATE 1680640000ULL
@@ -1891,6 +1912,8 @@ long prcmu_round_clock_rate(u8 clock, unsigned long rate)
{
if (clock < PRCMU_NUM_REG_CLOCKS)
return round_clock_rate(clock, rate);
+ else if (clock == PRCMU_ARMSS)
+ return round_armss_rate(rate);
else if (clock == PRCMU_PLLDSI)
return round_plldsi_rate(rate);
else if ((clock == PRCMU_DSI0CLK) || (clock == PRCMU_DSI1CLK))
@@ -1950,6 +1973,27 @@ static void set_clock_rate(u8 clock, unsigned long rate)
spin_unlock_irqrestore(&clk_mgt_lock, flags);
}
+static int set_armss_rate(unsigned long rate)
+{
+ int i = 0;
+
+ /* cpufreq table frequencies is in KHz. */
+ rate = rate / 1000;
+
+ /* Find the corresponding arm opp from the cpufreq table. */
+ while (db8500_cpufreq_table[i].frequency != CPUFREQ_TABLE_END) {
+ if (db8500_cpufreq_table[i].frequency == rate)
+ break;
+ i++;
+ }
+
+ if (db8500_cpufreq_table[i].frequency != rate)
+ return -EINVAL;
+
+ /* Set the new arm opp. */
+ return db8500_prcmu_set_arm_opp(db8500_cpufreq_table[i].index);
+}
+
static int set_plldsi_rate(unsigned long rate)
{
unsigned long src_rate;
@@ -2030,6 +2074,8 @@ int prcmu_set_clock_rate(u8 clock, unsigned long rate)
{
if (clock < PRCMU_NUM_REG_CLOCKS)
set_clock_rate(clock, rate);
+ else if (clock == PRCMU_ARMSS)
+ return set_armss_rate(rate);
else if (clock == PRCMU_PLLDSI)
return set_plldsi_rate(rate);
else if ((clock == PRCMU_DSI0CLK) || (clock == PRCMU_DSI1CLK))
@@ -2697,9 +2743,15 @@ static struct irq_domain_ops db8500_irq_ops = {
static int db8500_irq_init(struct device_node *np)
{
- db8500_irq_domain = irq_domain_add_legacy(
- np, NUM_PRCMU_WAKEUPS, IRQ_PRCMU_BASE,
- 0, &db8500_irq_ops, NULL);
+ int irq_base = -1;
+
+ /* In the device tree case, just take some IRQs */
+ if (!np)
+ irq_base = IRQ_PRCMU_BASE;
+
+ db8500_irq_domain = irq_domain_add_simple(
+ np, NUM_PRCMU_WAKEUPS, irq_base,
+ &db8500_irq_ops, NULL);
if (!db8500_irq_domain) {
pr_err("Failed to create irqdomain\n");
@@ -2754,8 +2806,6 @@ void __init db8500_prcmu_early_init(void)
init_completion(&mb5_transfer.work);
INIT_WORK(&mb0_transfer.mask_work, prcmu_mask_work);
-
- compute_armss_rate();
}
static void __init init_prcm_registers(void)
@@ -3020,6 +3070,8 @@ static struct mfd_cell db8500_prcmu_devs[] = {
{
.name = "cpufreq-u8500",
.of_compatible = "stericsson,cpufreq-u8500",
+ .platform_data = &db8500_cpufreq_table,
+ .pdata_size = sizeof(db8500_cpufreq_table),
},
{
.name = "ab8500-core",
@@ -3030,11 +3082,19 @@ static struct mfd_cell db8500_prcmu_devs[] = {
},
};
+static void db8500_prcmu_update_cpufreq(void)
+{
+ if (prcmu_has_arm_maxopp()) {
+ db8500_cpufreq_table[3].frequency = 1000000;
+ db8500_cpufreq_table[3].index = ARM_MAX_OPP;
+ }
+}
+
/**
* prcmu_fw_init - arch init call for the Linux PRCMU fw init logic
*
*/
-static int __devinit db8500_prcmu_probe(struct platform_device *pdev)
+static int db8500_prcmu_probe(struct platform_device *pdev)
{
struct ab8500_platform_data *ab8500_platdata = pdev->dev.platform_data;
struct device_node *np = pdev->dev.of_node;
@@ -3074,6 +3134,8 @@ static int __devinit db8500_prcmu_probe(struct platform_device *pdev)
if (cpu_is_u8500v20_or_later())
prcmu_config_esram0_deep_sleep(ESRAM0_DEEP_SLEEP_STATE_RET);
+ db8500_prcmu_update_cpufreq();
+
err = mfd_add_devices(&pdev->dev, 0, db8500_prcmu_devs,
ARRAY_SIZE(db8500_prcmu_devs), NULL, 0, NULL);
if (err) {
diff --git a/drivers/mfd/ezx-pcap.c b/drivers/mfd/ezx-pcap.c
index db662e2dcfa5..b7a61f0f27a4 100644
--- a/drivers/mfd/ezx-pcap.c
+++ b/drivers/mfd/ezx-pcap.c
@@ -371,7 +371,7 @@ static int pcap_remove_subdev(struct device *dev, void *unused)
return 0;
}
-static int __devinit pcap_add_subdev(struct pcap_chip *pcap,
+static int pcap_add_subdev(struct pcap_chip *pcap,
struct pcap_subdev *subdev)
{
struct platform_device *pdev;
@@ -391,7 +391,7 @@ static int __devinit pcap_add_subdev(struct pcap_chip *pcap,
return ret;
}
-static int __devexit ezx_pcap_remove(struct spi_device *spi)
+static int ezx_pcap_remove(struct spi_device *spi)
{
struct pcap_chip *pcap = dev_get_drvdata(&spi->dev);
struct pcap_platform_data *pdata = spi->dev.platform_data;
@@ -420,7 +420,7 @@ static int __devexit ezx_pcap_remove(struct spi_device *spi)
return 0;
}
-static int __devinit ezx_pcap_probe(struct spi_device *spi)
+static int ezx_pcap_probe(struct spi_device *spi)
{
struct pcap_platform_data *pdata = spi->dev.platform_data;
struct pcap_chip *pcap;
@@ -525,7 +525,7 @@ ret:
static struct spi_driver ezxpcap_driver = {
.probe = ezx_pcap_probe,
- .remove = __devexit_p(ezx_pcap_remove),
+ .remove = ezx_pcap_remove,
.driver = {
.name = "ezx-pcap",
.owner = THIS_MODULE,
diff --git a/drivers/mfd/htc-i2cpld.c b/drivers/mfd/htc-i2cpld.c
index d55065cc324c..324187c0c124 100644
--- a/drivers/mfd/htc-i2cpld.c
+++ b/drivers/mfd/htc-i2cpld.c
@@ -327,7 +327,7 @@ static void htcpld_chip_reset(struct i2c_client *client)
client, (chip_data->cache_out = chip_data->reset));
}
-static int __devinit htcpld_setup_chip_irq(
+static int htcpld_setup_chip_irq(
struct platform_device *pdev,
int chip_index)
{
@@ -361,7 +361,7 @@ static int __devinit htcpld_setup_chip_irq(
return ret;
}
-static int __devinit htcpld_register_chip_i2c(
+static int htcpld_register_chip_i2c(
struct platform_device *pdev,
int chip_index)
{
@@ -419,7 +419,7 @@ static int __devinit htcpld_register_chip_i2c(
return 0;
}
-static void __devinit htcpld_unregister_chip_i2c(
+static void htcpld_unregister_chip_i2c(
struct platform_device *pdev,
int chip_index)
{
@@ -434,7 +434,7 @@ static void __devinit htcpld_unregister_chip_i2c(
i2c_unregister_device(chip->client);
}
-static int __devinit htcpld_register_chip_gpio(
+static int htcpld_register_chip_gpio(
struct platform_device *pdev,
int chip_index)
{
@@ -501,7 +501,7 @@ static int __devinit htcpld_register_chip_gpio(
return 0;
}
-static int __devinit htcpld_setup_chips(struct platform_device *pdev)
+static int htcpld_setup_chips(struct platform_device *pdev)
{
struct htcpld_data *htcpld;
struct device *dev = &pdev->dev;
@@ -563,7 +563,7 @@ static int __devinit htcpld_setup_chips(struct platform_device *pdev)
return 0;
}
-static int __devinit htcpld_core_probe(struct platform_device *pdev)
+static int htcpld_core_probe(struct platform_device *pdev)
{
struct htcpld_data *htcpld;
struct device *dev = &pdev->dev;
diff --git a/drivers/mfd/intel_msic.c b/drivers/mfd/intel_msic.c
index 266bdc5bd96d..ab8d0b2739b2 100644
--- a/drivers/mfd/intel_msic.c
+++ b/drivers/mfd/intel_msic.c
@@ -306,7 +306,7 @@ int intel_msic_irq_read(struct intel_msic *msic, unsigned short reg, u8 *val)
}
EXPORT_SYMBOL_GPL(intel_msic_irq_read);
-static int __devinit intel_msic_init_devices(struct intel_msic *msic)
+static int intel_msic_init_devices(struct intel_msic *msic)
{
struct platform_device *pdev = msic->pdev;
struct intel_msic_platform_data *pdata = pdev->dev.platform_data;
@@ -364,7 +364,7 @@ fail:
return ret;
}
-static void __devexit intel_msic_remove_devices(struct intel_msic *msic)
+static void intel_msic_remove_devices(struct intel_msic *msic)
{
struct platform_device *pdev = msic->pdev;
struct intel_msic_platform_data *pdata = pdev->dev.platform_data;
@@ -375,7 +375,7 @@ static void __devexit intel_msic_remove_devices(struct intel_msic *msic)
gpio_free(pdata->ocd->gpio);
}
-static int __devinit intel_msic_probe(struct platform_device *pdev)
+static int intel_msic_probe(struct platform_device *pdev)
{
struct intel_msic_platform_data *pdata = pdev->dev.platform_data;
struct intel_msic *msic;
@@ -445,7 +445,7 @@ static int __devinit intel_msic_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit intel_msic_remove(struct platform_device *pdev)
+static int intel_msic_remove(struct platform_device *pdev)
{
struct intel_msic *msic = platform_get_drvdata(pdev);
@@ -457,7 +457,7 @@ static int __devexit intel_msic_remove(struct platform_device *pdev)
static struct platform_driver intel_msic_driver = {
.probe = intel_msic_probe,
- .remove = __devexit_p(intel_msic_remove),
+ .remove = intel_msic_remove,
.driver = {
.name = "intel_msic",
.owner = THIS_MODULE,
diff --git a/drivers/mfd/janz-cmodio.c b/drivers/mfd/janz-cmodio.c
index 965c4801df8a..45ece11cc27c 100644
--- a/drivers/mfd/janz-cmodio.c
+++ b/drivers/mfd/janz-cmodio.c
@@ -63,7 +63,7 @@ struct cmodio_device {
* Subdevices using the mfd-core API
*/
-static int __devinit cmodio_setup_subdevice(struct cmodio_device *priv,
+static int cmodio_setup_subdevice(struct cmodio_device *priv,
char *name, unsigned int devno,
unsigned int modno)
{
@@ -120,7 +120,7 @@ static int __devinit cmodio_setup_subdevice(struct cmodio_device *priv,
}
/* Probe each submodule using kernel parameters */
-static int __devinit cmodio_probe_submodules(struct cmodio_device *priv)
+static int cmodio_probe_submodules(struct cmodio_device *priv)
{
struct pci_dev *pdev = priv->pdev;
unsigned int num_probed = 0;
@@ -177,7 +177,7 @@ static const struct attribute_group cmodio_sysfs_attr_group = {
* PCI Driver
*/
-static int __devinit cmodio_pci_probe(struct pci_dev *dev,
+static int cmodio_pci_probe(struct pci_dev *dev,
const struct pci_device_id *id)
{
struct cmodio_device *priv;
@@ -254,7 +254,7 @@ out_return:
return ret;
}
-static void __devexit cmodio_pci_remove(struct pci_dev *dev)
+static void cmodio_pci_remove(struct pci_dev *dev)
{
struct cmodio_device *priv = pci_get_drvdata(dev);
@@ -280,7 +280,7 @@ static struct pci_driver cmodio_pci_driver = {
.name = DRV_NAME,
.id_table = cmodio_pci_ids,
.probe = cmodio_pci_probe,
- .remove = __devexit_p(cmodio_pci_remove),
+ .remove = cmodio_pci_remove,
};
module_pci_driver(cmodio_pci_driver);
diff --git a/drivers/mfd/jz4740-adc.c b/drivers/mfd/jz4740-adc.c
index c6b6d7dda517..0b8b55bb9b11 100644
--- a/drivers/mfd/jz4740-adc.c
+++ b/drivers/mfd/jz4740-adc.c
@@ -202,7 +202,7 @@ static struct mfd_cell jz4740_adc_cells[] = {
},
};
-static int __devinit jz4740_adc_probe(struct platform_device *pdev)
+static int jz4740_adc_probe(struct platform_device *pdev)
{
struct irq_chip_generic *gc;
struct irq_chip_type *ct;
@@ -307,7 +307,7 @@ err_free:
return ret;
}
-static int __devexit jz4740_adc_remove(struct platform_device *pdev)
+static int jz4740_adc_remove(struct platform_device *pdev)
{
struct jz4740_adc *adc = platform_get_drvdata(pdev);
@@ -332,7 +332,7 @@ static int __devexit jz4740_adc_remove(struct platform_device *pdev)
static struct platform_driver jz4740_adc_driver = {
.probe = jz4740_adc_probe,
- .remove = __devexit_p(jz4740_adc_remove),
+ .remove = jz4740_adc_remove,
.driver = {
.name = "jz4740-adc",
.owner = THIS_MODULE,
diff --git a/drivers/mfd/lm3533-core.c b/drivers/mfd/lm3533-core.c
index 24212f45b201..ceebf2c1ea97 100644
--- a/drivers/mfd/lm3533-core.c
+++ b/drivers/mfd/lm3533-core.c
@@ -382,7 +382,7 @@ static struct attribute_group lm3533_attribute_group = {
.attrs = lm3533_attributes
};
-static int __devinit lm3533_device_als_init(struct lm3533 *lm3533)
+static int lm3533_device_als_init(struct lm3533 *lm3533)
{
struct lm3533_platform_data *pdata = lm3533->dev->platform_data;
int ret;
@@ -405,7 +405,7 @@ static int __devinit lm3533_device_als_init(struct lm3533 *lm3533)
return 0;
}
-static int __devinit lm3533_device_bl_init(struct lm3533 *lm3533)
+static int lm3533_device_bl_init(struct lm3533 *lm3533)
{
struct lm3533_platform_data *pdata = lm3533->dev->platform_data;
int i;
@@ -434,7 +434,7 @@ static int __devinit lm3533_device_bl_init(struct lm3533 *lm3533)
return 0;
}
-static int __devinit lm3533_device_led_init(struct lm3533 *lm3533)
+static int lm3533_device_led_init(struct lm3533 *lm3533)
{
struct lm3533_platform_data *pdata = lm3533->dev->platform_data;
int i;
@@ -463,7 +463,7 @@ static int __devinit lm3533_device_led_init(struct lm3533 *lm3533)
return 0;
}
-static int __devinit lm3533_device_setup(struct lm3533 *lm3533,
+static int lm3533_device_setup(struct lm3533 *lm3533,
struct lm3533_platform_data *pdata)
{
int ret;
@@ -479,7 +479,7 @@ static int __devinit lm3533_device_setup(struct lm3533 *lm3533,
return 0;
}
-static int __devinit lm3533_device_init(struct lm3533 *lm3533)
+static int lm3533_device_init(struct lm3533 *lm3533)
{
struct lm3533_platform_data *pdata = lm3533->dev->platform_data;
int ret;
@@ -534,7 +534,7 @@ err_disable:
return ret;
}
-static void __devexit lm3533_device_exit(struct lm3533 *lm3533)
+static void lm3533_device_exit(struct lm3533 *lm3533)
{
dev_dbg(lm3533->dev, "%s\n", __func__);
@@ -596,7 +596,7 @@ static struct regmap_config regmap_config = {
.precious_reg = lm3533_precious_register,
};
-static int __devinit lm3533_i2c_probe(struct i2c_client *i2c,
+static int lm3533_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct lm3533 *lm3533;
@@ -624,7 +624,7 @@ static int __devinit lm3533_i2c_probe(struct i2c_client *i2c,
return 0;
}
-static int __devexit lm3533_i2c_remove(struct i2c_client *i2c)
+static int lm3533_i2c_remove(struct i2c_client *i2c)
{
struct lm3533 *lm3533 = i2c_get_clientdata(i2c);
@@ -648,7 +648,7 @@ static struct i2c_driver lm3533_i2c_driver = {
},
.id_table = lm3533_i2c_ids,
.probe = lm3533_i2c_probe,
- .remove = __devexit_p(lm3533_i2c_remove),
+ .remove = lm3533_i2c_remove,
};
static int __init lm3533_i2c_init(void)
diff --git a/drivers/mfd/lp8788.c b/drivers/mfd/lp8788.c
index 3e94a699833c..c3d3c9b4d3ad 100644
--- a/drivers/mfd/lp8788.c
+++ b/drivers/mfd/lp8788.c
@@ -203,7 +203,7 @@ static int lp8788_probe(struct i2c_client *cl, const struct i2c_device_id *id)
ARRAY_SIZE(lp8788_devs), NULL, 0, NULL);
}
-static int __devexit lp8788_remove(struct i2c_client *cl)
+static int lp8788_remove(struct i2c_client *cl)
{
struct lp8788 *lp = i2c_get_clientdata(cl);
@@ -224,7 +224,7 @@ static struct i2c_driver lp8788_driver = {
.owner = THIS_MODULE,
},
.probe = lp8788_probe,
- .remove = __devexit_p(lp8788_remove),
+ .remove = lp8788_remove,
.id_table = lp8788_ids,
};
diff --git a/drivers/mfd/lpc_ich.c b/drivers/mfd/lpc_ich.c
index a22544fe5319..2ad24caa07db 100644
--- a/drivers/mfd/lpc_ich.c
+++ b/drivers/mfd/lpc_ich.c
@@ -196,7 +196,7 @@ enum lpc_chipsets {
LPC_LPT_LP, /* Lynx Point-LP */
};
-struct lpc_ich_info lpc_chipset_info[] __devinitdata = {
+struct lpc_ich_info lpc_chipset_info[] = {
[LPC_ICH] = {
.name = "ICH",
.iTCO_version = 1,
@@ -672,7 +672,7 @@ static void lpc_ich_restore_config_space(struct pci_dev *dev)
}
}
-static void __devinit lpc_ich_enable_acpi_space(struct pci_dev *dev)
+static void lpc_ich_enable_acpi_space(struct pci_dev *dev)
{
u8 reg_save;
@@ -681,7 +681,7 @@ static void __devinit lpc_ich_enable_acpi_space(struct pci_dev *dev)
lpc_ich_acpi_save = reg_save;
}
-static void __devinit lpc_ich_enable_gpio_space(struct pci_dev *dev)
+static void lpc_ich_enable_gpio_space(struct pci_dev *dev)
{
u8 reg_save;
@@ -690,7 +690,7 @@ static void __devinit lpc_ich_enable_gpio_space(struct pci_dev *dev)
lpc_ich_gpio_save = reg_save;
}
-static void __devinit lpc_ich_finalize_cell(struct mfd_cell *cell,
+static void lpc_ich_finalize_cell(struct mfd_cell *cell,
const struct pci_device_id *id)
{
cell->platform_data = &lpc_chipset_info[id->driver_data];
@@ -702,7 +702,7 @@ static void __devinit lpc_ich_finalize_cell(struct mfd_cell *cell,
* GPIO groups and it's enough to have access to one of these to instantiate
* the device.
*/
-static int __devinit lpc_ich_check_conflict_gpio(struct resource *res)
+static int lpc_ich_check_conflict_gpio(struct resource *res)
{
int ret;
u8 use_gpio = 0;
@@ -721,7 +721,7 @@ static int __devinit lpc_ich_check_conflict_gpio(struct resource *res)
return use_gpio ? use_gpio : ret;
}
-static int __devinit lpc_ich_init_gpio(struct pci_dev *dev,
+static int lpc_ich_init_gpio(struct pci_dev *dev,
const struct pci_device_id *id)
{
u32 base_addr_cfg;
@@ -798,7 +798,7 @@ gpio_done:
return ret;
}
-static int __devinit lpc_ich_init_wdt(struct pci_dev *dev,
+static int lpc_ich_init_wdt(struct pci_dev *dev,
const struct pci_device_id *id)
{
u32 base_addr_cfg;
@@ -852,7 +852,7 @@ wdt_done:
return ret;
}
-static int __devinit lpc_ich_probe(struct pci_dev *dev,
+static int lpc_ich_probe(struct pci_dev *dev,
const struct pci_device_id *id)
{
int ret;
@@ -878,7 +878,7 @@ static int __devinit lpc_ich_probe(struct pci_dev *dev,
return 0;
}
-static void __devexit lpc_ich_remove(struct pci_dev *dev)
+static void lpc_ich_remove(struct pci_dev *dev)
{
mfd_remove_devices(&dev->dev);
lpc_ich_restore_config_space(dev);
@@ -888,7 +888,7 @@ static struct pci_driver lpc_ich_driver = {
.name = "lpc_ich",
.id_table = lpc_ich_ids,
.probe = lpc_ich_probe,
- .remove = __devexit_p(lpc_ich_remove),
+ .remove = lpc_ich_remove,
};
static int __init lpc_ich_init(void)
diff --git a/drivers/mfd/lpc_sch.c b/drivers/mfd/lpc_sch.c
index f6b9c5c96b24..5624fcbba69b 100644
--- a/drivers/mfd/lpc_sch.c
+++ b/drivers/mfd/lpc_sch.c
@@ -83,7 +83,7 @@ static DEFINE_PCI_DEVICE_TABLE(lpc_sch_ids) = {
};
MODULE_DEVICE_TABLE(pci, lpc_sch_ids);
-static int __devinit lpc_sch_probe(struct pci_dev *dev,
+static int lpc_sch_probe(struct pci_dev *dev,
const struct pci_device_id *id)
{
unsigned int base_addr_cfg;
@@ -164,7 +164,7 @@ out_dev:
return ret;
}
-static void __devexit lpc_sch_remove(struct pci_dev *dev)
+static void lpc_sch_remove(struct pci_dev *dev)
{
mfd_remove_devices(&dev->dev);
}
@@ -173,7 +173,7 @@ static struct pci_driver lpc_sch_driver = {
.name = "lpc_sch",
.id_table = lpc_sch_ids,
.probe = lpc_sch_probe,
- .remove = __devexit_p(lpc_sch_remove),
+ .remove = lpc_sch_remove,
};
module_pci_driver(lpc_sch_driver);
diff --git a/drivers/mfd/max77686.c b/drivers/mfd/max77686.c
index d9e24c849a00..f6878f8db57d 100644
--- a/drivers/mfd/max77686.c
+++ b/drivers/mfd/max77686.c
@@ -45,7 +45,7 @@ static struct regmap_config max77686_regmap_config = {
};
#ifdef CONFIG_OF
-static struct of_device_id __devinitdata max77686_pmic_dt_match[] = {
+static struct of_device_id max77686_pmic_dt_match[] = {
{.compatible = "maxim,max77686", .data = 0},
{},
};
diff --git a/drivers/mfd/max8907.c b/drivers/mfd/max8907.c
index 17f2593d82b8..e9b1c93a3ade 100644
--- a/drivers/mfd/max8907.c
+++ b/drivers/mfd/max8907.c
@@ -183,7 +183,7 @@ static void max8907_power_off(void)
MAX8907_MASK_POWER_OFF, MAX8907_MASK_POWER_OFF);
}
-static __devinit int max8907_i2c_probe(struct i2c_client *i2c,
+static int max8907_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct max8907 *max8907;
@@ -288,7 +288,7 @@ err_alloc_drvdata:
return ret;
}
-static __devexit int max8907_i2c_remove(struct i2c_client *i2c)
+static int max8907_i2c_remove(struct i2c_client *i2c)
{
struct max8907 *max8907 = i2c_get_clientdata(i2c);
diff --git a/drivers/mfd/max8925-core.c b/drivers/mfd/max8925-core.c
index 9f54c04912f2..e32466e865b9 100644
--- a/drivers/mfd/max8925-core.c
+++ b/drivers/mfd/max8925-core.c
@@ -19,12 +19,12 @@
#include <linux/mfd/core.h>
#include <linux/mfd/max8925.h>
-static struct resource bk_resources[] __devinitdata = {
+static struct resource bk_resources[] = {
{ 0x84, 0x84, "mode control", IORESOURCE_REG, },
{ 0x85, 0x85, "control", IORESOURCE_REG, },
};
-static struct mfd_cell bk_devs[] __devinitdata = {
+static struct mfd_cell bk_devs[] = {
{
.name = "max8925-backlight",
.num_resources = ARRAY_SIZE(bk_resources),
@@ -110,99 +110,99 @@ static struct mfd_cell onkey_devs[] = {
},
};
-static struct resource sd1_resources[] __devinitdata = {
+static struct resource sd1_resources[] = {
{0x06, 0x06, "sdv", IORESOURCE_REG, },
};
-static struct resource sd2_resources[] __devinitdata = {
+static struct resource sd2_resources[] = {
{0x09, 0x09, "sdv", IORESOURCE_REG, },
};
-static struct resource sd3_resources[] __devinitdata = {
+static struct resource sd3_resources[] = {
{0x0c, 0x0c, "sdv", IORESOURCE_REG, },
};
-static struct resource ldo1_resources[] __devinitdata = {
+static struct resource ldo1_resources[] = {
{0x1a, 0x1a, "ldov", IORESOURCE_REG, },
};
-static struct resource ldo2_resources[] __devinitdata = {
+static struct resource ldo2_resources[] = {
{0x1e, 0x1e, "ldov", IORESOURCE_REG, },
};
-static struct resource ldo3_resources[] __devinitdata = {
+static struct resource ldo3_resources[] = {
{0x22, 0x22, "ldov", IORESOURCE_REG, },
};
-static struct resource ldo4_resources[] __devinitdata = {
+static struct resource ldo4_resources[] = {
{0x26, 0x26, "ldov", IORESOURCE_REG, },
};
-static struct resource ldo5_resources[] __devinitdata = {
+static struct resource ldo5_resources[] = {
{0x2a, 0x2a, "ldov", IORESOURCE_REG, },
};
-static struct resource ldo6_resources[] __devinitdata = {
+static struct resource ldo6_resources[] = {
{0x2e, 0x2e, "ldov", IORESOURCE_REG, },
};
-static struct resource ldo7_resources[] __devinitdata = {
+static struct resource ldo7_resources[] = {
{0x32, 0x32, "ldov", IORESOURCE_REG, },
};
-static struct resource ldo8_resources[] __devinitdata = {
+static struct resource ldo8_resources[] = {
{0x36, 0x36, "ldov", IORESOURCE_REG, },
};
-static struct resource ldo9_resources[] __devinitdata = {
+static struct resource ldo9_resources[] = {
{0x3a, 0x3a, "ldov", IORESOURCE_REG, },
};
-static struct resource ldo10_resources[] __devinitdata = {
+static struct resource ldo10_resources[] = {
{0x3e, 0x3e, "ldov", IORESOURCE_REG, },
};
-static struct resource ldo11_resources[] __devinitdata = {
+static struct resource ldo11_resources[] = {
{0x42, 0x42, "ldov", IORESOURCE_REG, },
};
-static struct resource ldo12_resources[] __devinitdata = {
+static struct resource ldo12_resources[] = {
{0x46, 0x46, "ldov", IORESOURCE_REG, },
};
-static struct resource ldo13_resources[] __devinitdata = {
+static struct resource ldo13_resources[] = {
{0x4a, 0x4a, "ldov", IORESOURCE_REG, },
};
-static struct resource ldo14_resources[] __devinitdata = {
+static struct resource ldo14_resources[] = {
{0x4e, 0x4e, "ldov", IORESOURCE_REG, },
};
-static struct resource ldo15_resources[] __devinitdata = {
+static struct resource ldo15_resources[] = {
{0x52, 0x52, "ldov", IORESOURCE_REG, },
};
-static struct resource ldo16_resources[] __devinitdata = {
+static struct resource ldo16_resources[] = {
{0x12, 0x12, "ldov", IORESOURCE_REG, },
};
-static struct resource ldo17_resources[] __devinitdata = {
+static struct resource ldo17_resources[] = {
{0x16, 0x16, "ldov", IORESOURCE_REG, },
};
-static struct resource ldo18_resources[] __devinitdata = {
+static struct resource ldo18_resources[] = {
{0x74, 0x74, "ldov", IORESOURCE_REG, },
};
-static struct resource ldo19_resources[] __devinitdata = {
+static struct resource ldo19_resources[] = {
{0x5e, 0x5e, "ldov", IORESOURCE_REG, },
};
-static struct resource ldo20_resources[] __devinitdata = {
+static struct resource ldo20_resources[] = {
{0x9e, 0x9e, "ldov", IORESOURCE_REG, },
};
-static struct mfd_cell reg_devs[] __devinitdata = {
+static struct mfd_cell reg_devs[] = {
{
.name = "max8925-regulator",
.id = 0,
@@ -714,7 +714,7 @@ tsc_irq:
return 0;
}
-static void __devinit init_regulator(struct max8925_chip *chip,
+static void init_regulator(struct max8925_chip *chip,
struct max8925_platform_data *pdata)
{
int ret;
@@ -821,7 +821,7 @@ static void __devinit init_regulator(struct max8925_chip *chip,
}
}
-int __devinit max8925_device_init(struct max8925_chip *chip,
+int max8925_device_init(struct max8925_chip *chip,
struct max8925_platform_data *pdata)
{
int ret;
@@ -901,7 +901,7 @@ out:
return ret;
}
-void __devexit max8925_device_exit(struct max8925_chip *chip)
+void max8925_device_exit(struct max8925_chip *chip)
{
if (chip->core_irq)
free_irq(chip->core_irq, chip);
diff --git a/drivers/mfd/max8925-i2c.c b/drivers/mfd/max8925-i2c.c
index d9e4b36edee9..00b5b456063d 100644
--- a/drivers/mfd/max8925-i2c.c
+++ b/drivers/mfd/max8925-i2c.c
@@ -135,7 +135,7 @@ static const struct i2c_device_id max8925_id_table[] = {
};
MODULE_DEVICE_TABLE(i2c, max8925_id_table);
-static int __devinit max8925_probe(struct i2c_client *client,
+static int max8925_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct max8925_platform_data *pdata = client->dev.platform_data;
@@ -168,7 +168,7 @@ static int __devinit max8925_probe(struct i2c_client *client,
return 0;
}
-static int __devexit max8925_remove(struct i2c_client *client)
+static int max8925_remove(struct i2c_client *client)
{
struct max8925_chip *chip = i2c_get_clientdata(client);
@@ -210,7 +210,7 @@ static struct i2c_driver max8925_driver = {
.pm = &max8925_pm_ops,
},
.probe = max8925_probe,
- .remove = __devexit_p(max8925_remove),
+ .remove = max8925_remove,
.id_table = max8925_id_table,
};
diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c
index f123517065ec..abd5c80c7cf5 100644
--- a/drivers/mfd/max8997.c
+++ b/drivers/mfd/max8997.c
@@ -21,8 +21,10 @@
* This driver is based on max8998.c
*/
+#include <linux/err.h>
#include <linux/slab.h>
#include <linux/i2c.h>
+#include <linux/of_irq.h>
#include <linux/interrupt.h>
#include <linux/pm_runtime.h>
#include <linux/module.h>
@@ -47,6 +49,13 @@ static struct mfd_cell max8997_devs[] = {
{ .name = "max8997-led", .id = 2 },
};
+#ifdef CONFIG_OF
+static struct of_device_id __devinitdata max8997_pmic_dt_match[] = {
+ { .compatible = "maxim,max8997-pmic", .data = TYPE_MAX8997 },
+ {},
+};
+#endif
+
int max8997_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest)
{
struct max8997_dev *max8997 = i2c_get_clientdata(i2c);
@@ -123,6 +132,58 @@ int max8997_update_reg(struct i2c_client *i2c, u8 reg, u8 val, u8 mask)
}
EXPORT_SYMBOL_GPL(max8997_update_reg);
+#ifdef CONFIG_OF
+/*
+ * Only the common platform data elements for max8997 are parsed here from the
+ * device tree. Other sub-modules of max8997 such as pmic, rtc and others have
+ * to parse their own platform data elements from device tree.
+ *
+ * The max8997 platform data structure is instantiated here and the drivers for
+ * the sub-modules need not instantiate another instance while parsing their
+ * platform data.
+ */
+static struct max8997_platform_data *max8997_i2c_parse_dt_pdata(
+ struct device *dev)
+{
+ struct max8997_platform_data *pd;
+
+ pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
+ if (!pd) {
+ dev_err(dev, "could not allocate memory for pdata\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ pd->ono = irq_of_parse_and_map(dev->of_node, 1);
+
+ /*
+ * ToDo: the 'wakeup' member in the platform data is more of a linux
+ * specfic information. Hence, there is no binding for that yet and
+ * not parsed here.
+ */
+
+ return pd;
+}
+#else
+static struct max8997_platform_data *max8997_i2c_parse_dt_pdata(
+ struct device *dev)
+{
+ return 0;
+}
+#endif
+
+static inline int max8997_i2c_get_driver_data(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+#ifdef CONFIG_OF
+ if (i2c->dev.of_node) {
+ const struct of_device_id *match;
+ match = of_match_node(max8997_pmic_dt_match, i2c->dev.of_node);
+ return (int)match->data;
+ }
+#endif
+ return (int)id->driver_data;
+}
+
static int max8997_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
@@ -137,12 +198,21 @@ static int max8997_i2c_probe(struct i2c_client *i2c,
i2c_set_clientdata(i2c, max8997);
max8997->dev = &i2c->dev;
max8997->i2c = i2c;
- max8997->type = id->driver_data;
+ max8997->type = max8997_i2c_get_driver_data(i2c, id);
max8997->irq = i2c->irq;
+ if (max8997->dev->of_node) {
+ pdata = max8997_i2c_parse_dt_pdata(max8997->dev);
+ if (IS_ERR(pdata)) {
+ ret = PTR_ERR(pdata);
+ goto err;
+ }
+ }
+
if (!pdata)
goto err;
+ max8997->pdata = pdata;
max8997->ono = pdata->ono;
mutex_init(&max8997->iolock);
@@ -434,6 +504,7 @@ static struct i2c_driver max8997_i2c_driver = {
.name = "max8997",
.owner = THIS_MODULE,
.pm = &max8997_pm,
+ .of_match_table = of_match_ptr(max8997_pmic_dt_match),
},
.probe = max8997_i2c_probe,
.remove = max8997_i2c_remove,
diff --git a/drivers/mfd/mc13xxx-i2c.c b/drivers/mfd/mc13xxx-i2c.c
index 9d18dde3cd2a..7957999f30bb 100644
--- a/drivers/mfd/mc13xxx-i2c.c
+++ b/drivers/mfd/mc13xxx-i2c.c
@@ -85,7 +85,7 @@ static int mc13xxx_i2c_probe(struct i2c_client *client,
return ret;
}
-static int __devexit mc13xxx_i2c_remove(struct i2c_client *client)
+static int mc13xxx_i2c_remove(struct i2c_client *client)
{
struct mc13xxx *mc13xxx = dev_get_drvdata(&client->dev);
@@ -102,7 +102,7 @@ static struct i2c_driver mc13xxx_i2c_driver = {
.of_match_table = mc13xxx_dt_ids,
},
.probe = mc13xxx_i2c_probe,
- .remove = __devexit_p(mc13xxx_i2c_remove),
+ .remove = mc13xxx_i2c_remove,
};
static int __init mc13xxx_i2c_init(void)
diff --git a/drivers/mfd/mc13xxx-spi.c b/drivers/mfd/mc13xxx-spi.c
index 0bdb43a0aff0..cb32f69d80ba 100644
--- a/drivers/mfd/mc13xxx-spi.c
+++ b/drivers/mfd/mc13xxx-spi.c
@@ -159,7 +159,7 @@ static int mc13xxx_spi_probe(struct spi_device *spi)
return ret;
}
-static int __devexit mc13xxx_spi_remove(struct spi_device *spi)
+static int mc13xxx_spi_remove(struct spi_device *spi)
{
struct mc13xxx *mc13xxx = dev_get_drvdata(&spi->dev);
@@ -176,7 +176,7 @@ static struct spi_driver mc13xxx_spi_driver = {
.of_match_table = mc13xxx_dt_ids,
},
.probe = mc13xxx_spi_probe,
- .remove = __devexit_p(mc13xxx_spi_remove),
+ .remove = mc13xxx_spi_remove,
};
static int __init mc13xxx_init(void)
diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c
index 55d589981412..998ce8cb3065 100644
--- a/drivers/mfd/menelaus.c
+++ b/drivers/mfd/menelaus.c
@@ -41,11 +41,11 @@
#include <linux/rtc.h>
#include <linux/bcd.h>
#include <linux/slab.h>
+#include <linux/mfd/menelaus.h>
#include <asm/mach/irq.h>
#include <asm/gpio.h>
-#include <plat/menelaus.h>
#define DRIVER_NAME "menelaus"
diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
index 23cec57c02ba..770a0d01e0b9 100644
--- a/drivers/mfd/omap-usb-host.c
+++ b/drivers/mfd/omap-usb-host.c
@@ -26,9 +26,12 @@
#include <linux/spinlock.h>
#include <linux/gpio.h>
#include <plat/cpu.h>
-#include <plat/usb.h>
+#include <linux/platform_device.h>
+#include <linux/platform_data/usb-omap.h>
#include <linux/pm_runtime.h>
+#include "omap-usb.h"
+
#define USBHS_DRIVER_NAME "usbhs_omap"
#define OMAP_EHCI_DEVICE "ehci-omap"
#define OMAP_OHCI_DEVICE "ohci-omap3"
@@ -464,7 +467,7 @@ static void omap_usbhs_deinit(struct device *dev)
*
* Allocates basic resources for this USB host controller.
*/
-static int __devinit usbhs_omap_probe(struct platform_device *pdev)
+static int usbhs_omap_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct usbhs_omap_platform_data *pdata = dev->platform_data;
@@ -652,7 +655,7 @@ end_probe:
*
* Reverses the effect of usbhs_omap_probe().
*/
-static int __devexit usbhs_omap_remove(struct platform_device *pdev)
+static int usbhs_omap_remove(struct platform_device *pdev)
{
struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev);
diff --git a/drivers/mfd/omap-usb-tll.c b/drivers/mfd/omap-usb-tll.c
index 4b7757b84301..eb869153206d 100644
--- a/drivers/mfd/omap-usb-tll.c
+++ b/drivers/mfd/omap-usb-tll.c
@@ -25,8 +25,8 @@
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/err.h>
-#include <plat/usb.h>
#include <linux/pm_runtime.h>
+#include <linux/platform_data/usb-omap.h>
#define USBTLL_DRIVER_NAME "usbhs_tll"
@@ -200,7 +200,7 @@ static unsigned ohci_omap3_fslsmode(enum usbhs_omap_port_mode mode)
*
* Allocates basic resources for this USB host controller.
*/
-static int __devinit usbtll_omap_probe(struct platform_device *pdev)
+static int usbtll_omap_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct usbtll_omap_platform_data *pdata = dev->platform_data;
@@ -348,7 +348,7 @@ end:
*
* Reverses the effect of usbtll_omap_probe().
*/
-static int __devexit usbtll_omap_remove(struct platform_device *pdev)
+static int usbtll_omap_remove(struct platform_device *pdev)
{
struct usbtll_omap *tll = platform_get_drvdata(pdev);
@@ -424,7 +424,7 @@ static struct platform_driver usbtll_omap_driver = {
.pm = &usbtllomap_dev_pm_ops,
},
.probe = usbtll_omap_probe,
- .remove = __devexit_p(usbtll_omap_remove),
+ .remove = usbtll_omap_remove,
};
int omap_tll_enable(void)
diff --git a/drivers/mfd/omap-usb.h b/drivers/mfd/omap-usb.h
new file mode 100644
index 000000000000..972aa961b064
--- /dev/null
+++ b/drivers/mfd/omap-usb.h
@@ -0,0 +1,2 @@
+extern int omap_tll_enable(void);
+extern int omap_tll_disable(void);
diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c
index 4f8d6e6b19aa..6ffd7a2affdc 100644
--- a/drivers/mfd/palmas.c
+++ b/drivers/mfd/palmas.c
@@ -247,7 +247,7 @@ static struct regmap_irq_chip palmas_irq_chip = {
PALMAS_INT1_MASK),
};
-static void __devinit palmas_dt_to_pdata(struct device_node *node,
+static void palmas_dt_to_pdata(struct device_node *node,
struct palmas_platform_data *pdata)
{
int ret;
@@ -275,7 +275,7 @@ static void __devinit palmas_dt_to_pdata(struct device_node *node,
PALMAS_POWER_CTRL_ENABLE2_MASK;
}
-static int __devinit palmas_i2c_probe(struct i2c_client *i2c,
+static int palmas_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct palmas *palmas;
@@ -492,7 +492,7 @@ static const struct i2c_device_id palmas_i2c_id[] = {
};
MODULE_DEVICE_TABLE(i2c, palmas_i2c_id);
-static struct of_device_id __devinitdata of_palmas_match_tbl[] = {
+static struct of_device_id of_palmas_match_tbl[] = {
{ .compatible = "ti,palmas", },
{ /* end */ }
};
diff --git a/drivers/mfd/pcf50633-adc.c b/drivers/mfd/pcf50633-adc.c
index 3927c17e4175..18b53cb72fea 100644
--- a/drivers/mfd/pcf50633-adc.c
+++ b/drivers/mfd/pcf50633-adc.c
@@ -199,7 +199,7 @@ static void pcf50633_adc_irq(int irq, void *data)
kfree(req);
}
-static int __devinit pcf50633_adc_probe(struct platform_device *pdev)
+static int pcf50633_adc_probe(struct platform_device *pdev)
{
struct pcf50633_adc *adc;
@@ -218,7 +218,7 @@ static int __devinit pcf50633_adc_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit pcf50633_adc_remove(struct platform_device *pdev)
+static int pcf50633_adc_remove(struct platform_device *pdev)
{
struct pcf50633_adc *adc = platform_get_drvdata(pdev);
int i, head;
@@ -246,7 +246,7 @@ static struct platform_driver pcf50633_adc_driver = {
.name = "pcf50633-adc",
},
.probe = pcf50633_adc_probe,
- .remove = __devexit_p(pcf50633_adc_remove),
+ .remove = pcf50633_adc_remove,
};
module_platform_driver(pcf50633_adc_driver);
diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c
index 45ce1fb5a549..64803f13bcec 100644
--- a/drivers/mfd/pcf50633-core.c
+++ b/drivers/mfd/pcf50633-core.c
@@ -191,7 +191,7 @@ static struct regmap_config pcf50633_regmap_config = {
.val_bits = 8,
};
-static int __devinit pcf50633_probe(struct i2c_client *client,
+static int pcf50633_probe(struct i2c_client *client,
const struct i2c_device_id *ids)
{
struct pcf50633 *pcf;
@@ -275,7 +275,7 @@ static int __devinit pcf50633_probe(struct i2c_client *client,
return 0;
}
-static int __devexit pcf50633_remove(struct i2c_client *client)
+static int pcf50633_remove(struct i2c_client *client)
{
struct pcf50633 *pcf = i2c_get_clientdata(client);
int i;
@@ -308,7 +308,7 @@ static struct i2c_driver pcf50633_driver = {
},
.id_table = pcf50633_id_table,
.probe = pcf50633_probe,
- .remove = __devexit_p(pcf50633_remove),
+ .remove = pcf50633_remove,
};
static int __init pcf50633_init(void)
diff --git a/drivers/mfd/pm8921-core.c b/drivers/mfd/pm8921-core.c
index e873b15753d8..d4b297cbd801 100644
--- a/drivers/mfd/pm8921-core.c
+++ b/drivers/mfd/pm8921-core.c
@@ -80,7 +80,7 @@ static struct pm8xxx_drvdata pm8921_drvdata = {
.pmic_read_irq_stat = pm8921_read_irq_stat,
};
-static int __devinit pm8921_add_subdevices(const struct pm8921_platform_data
+static int pm8921_add_subdevices(const struct pm8921_platform_data
*pdata,
struct pm8921 *pmic,
u32 rev)
@@ -104,7 +104,7 @@ static int __devinit pm8921_add_subdevices(const struct pm8921_platform_data
return ret;
}
-static int __devinit pm8921_probe(struct platform_device *pdev)
+static int pm8921_probe(struct platform_device *pdev)
{
const struct pm8921_platform_data *pdata = pdev->dev.platform_data;
struct pm8921 *pmic;
@@ -165,7 +165,7 @@ err_read_rev:
return rc;
}
-static int __devexit pm8921_remove(struct platform_device *pdev)
+static int pm8921_remove(struct platform_device *pdev)
{
struct pm8xxx_drvdata *drvdata;
struct pm8921 *pmic = NULL;
@@ -187,7 +187,7 @@ static int __devexit pm8921_remove(struct platform_device *pdev)
static struct platform_driver pm8921_driver = {
.probe = pm8921_probe,
- .remove = __devexit_p(pm8921_remove),
+ .remove = pm8921_remove,
.driver = {
.name = "pm8921-core",
.owner = THIS_MODULE,
diff --git a/drivers/mfd/pm8xxx-irq.c b/drivers/mfd/pm8xxx-irq.c
index d452dd013081..1360e20adf11 100644
--- a/drivers/mfd/pm8xxx-irq.c
+++ b/drivers/mfd/pm8xxx-irq.c
@@ -309,7 +309,7 @@ bail_out:
}
EXPORT_SYMBOL_GPL(pm8xxx_get_irq_stat);
-struct pm_irq_chip * __devinit pm8xxx_irq_init(struct device *dev,
+struct pm_irq_chip * pm8xxx_irq_init(struct device *dev,
const struct pm8xxx_irq_platform_data *pdata)
{
struct pm_irq_chip *chip;
@@ -363,7 +363,7 @@ struct pm_irq_chip * __devinit pm8xxx_irq_init(struct device *dev,
return chip;
}
-int __devexit pm8xxx_irq_exit(struct pm_irq_chip *chip)
+int pm8xxx_irq_exit(struct pm_irq_chip *chip)
{
irq_set_chained_handler(chip->devirq, NULL);
kfree(chip);
diff --git a/drivers/mfd/rc5t583.c b/drivers/mfd/rc5t583.c
index f1a024ecdb1e..14bdaccefbec 100644
--- a/drivers/mfd/rc5t583.c
+++ b/drivers/mfd/rc5t583.c
@@ -246,7 +246,7 @@ static const struct regmap_config rc5t583_regmap_config = {
.cache_type = REGCACHE_RBTREE,
};
-static int __devinit rc5t583_i2c_probe(struct i2c_client *i2c,
+static int rc5t583_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct rc5t583 *rc5t583;
@@ -303,7 +303,7 @@ err_add_devs:
return ret;
}
-static int __devexit rc5t583_i2c_remove(struct i2c_client *i2c)
+static int rc5t583_i2c_remove(struct i2c_client *i2c)
{
struct rc5t583 *rc5t583 = i2c_get_clientdata(i2c);
@@ -325,7 +325,7 @@ static struct i2c_driver rc5t583_i2c_driver = {
.owner = THIS_MODULE,
},
.probe = rc5t583_i2c_probe,
- .remove = __devexit_p(rc5t583_i2c_remove),
+ .remove = rc5t583_i2c_remove,
.id_table = rc5t583_i2c_id,
};
diff --git a/drivers/mfd/rdc321x-southbridge.c b/drivers/mfd/rdc321x-southbridge.c
index fbabc3cbe350..21b7bef73507 100644
--- a/drivers/mfd/rdc321x-southbridge.c
+++ b/drivers/mfd/rdc321x-southbridge.c
@@ -72,7 +72,7 @@ static struct mfd_cell rdc321x_sb_cells[] = {
},
};
-static int __devinit rdc321x_sb_probe(struct pci_dev *pdev,
+static int rdc321x_sb_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
int err;
@@ -91,7 +91,7 @@ static int __devinit rdc321x_sb_probe(struct pci_dev *pdev,
NULL, 0, NULL);
}
-static void __devexit rdc321x_sb_remove(struct pci_dev *pdev)
+static void rdc321x_sb_remove(struct pci_dev *pdev)
{
mfd_remove_devices(&pdev->dev);
}
@@ -106,7 +106,7 @@ static struct pci_driver rdc321x_sb_driver = {
.name = "RDC321x Southbridge",
.id_table = rdc321x_sb_table,
.probe = rdc321x_sb_probe,
- .remove = __devexit_p(rdc321x_sb_remove),
+ .remove = rdc321x_sb_remove,
};
module_pci_driver(rdc321x_sb_driver);
diff --git a/drivers/mfd/rtl8411.c b/drivers/mfd/rtl8411.c
new file mode 100644
index 000000000000..89f046ca9e41
--- /dev/null
+++ b/drivers/mfd/rtl8411.c
@@ -0,0 +1,251 @@
+/* Driver for Realtek PCI-Express card reader
+ *
+ * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ * Wei WANG <wei_wang@realsil.com.cn>
+ * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
+ */
+
+#include <linux/module.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/mfd/rtsx_pci.h>
+
+#include "rtsx_pcr.h"
+
+static u8 rtl8411_get_ic_version(struct rtsx_pcr *pcr)
+{
+ u8 val;
+
+ rtsx_pci_read_register(pcr, SYS_VER, &val);
+ return val & 0x0F;
+}
+
+static int rtl8411_extra_init_hw(struct rtsx_pcr *pcr)
+{
+ return rtsx_pci_write_register(pcr, CD_PAD_CTL,
+ CD_DISABLE_MASK | CD_AUTO_DISABLE, CD_ENABLE);
+}
+
+static int rtl8411_turn_on_led(struct rtsx_pcr *pcr)
+{
+ return rtsx_pci_write_register(pcr, CARD_GPIO, 0x01, 0x00);
+}
+
+static int rtl8411_turn_off_led(struct rtsx_pcr *pcr)
+{
+ return rtsx_pci_write_register(pcr, CARD_GPIO, 0x01, 0x01);
+}
+
+static int rtl8411_enable_auto_blink(struct rtsx_pcr *pcr)
+{
+ return rtsx_pci_write_register(pcr, CARD_AUTO_BLINK, 0xFF, 0x0D);
+}
+
+static int rtl8411_disable_auto_blink(struct rtsx_pcr *pcr)
+{
+ return rtsx_pci_write_register(pcr, CARD_AUTO_BLINK, 0x08, 0x00);
+}
+
+static int rtl8411_card_power_on(struct rtsx_pcr *pcr, int card)
+{
+ int err;
+
+ rtsx_pci_init_cmd(pcr);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
+ BPP_POWER_MASK, BPP_POWER_5_PERCENT_ON);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_CTL,
+ BPP_LDO_POWB, BPP_LDO_SUSPEND);
+ err = rtsx_pci_send_cmd(pcr, 100);
+ if (err < 0)
+ return err;
+
+ /* To avoid too large in-rush current */
+ udelay(150);
+
+ err = rtsx_pci_write_register(pcr, CARD_PWR_CTL,
+ BPP_POWER_MASK, BPP_POWER_10_PERCENT_ON);
+ if (err < 0)
+ return err;
+
+ udelay(150);
+
+ err = rtsx_pci_write_register(pcr, CARD_PWR_CTL,
+ BPP_POWER_MASK, BPP_POWER_15_PERCENT_ON);
+ if (err < 0)
+ return err;
+
+ udelay(150);
+
+ err = rtsx_pci_write_register(pcr, CARD_PWR_CTL,
+ BPP_POWER_MASK, BPP_POWER_ON);
+ if (err < 0)
+ return err;
+
+ return rtsx_pci_write_register(pcr, LDO_CTL, BPP_LDO_POWB, BPP_LDO_ON);
+}
+
+static int rtl8411_card_power_off(struct rtsx_pcr *pcr, int card)
+{
+ int err;
+
+ err = rtsx_pci_write_register(pcr, CARD_PWR_CTL,
+ BPP_POWER_MASK, BPP_POWER_OFF);
+ if (err < 0)
+ return err;
+
+ return rtsx_pci_write_register(pcr, LDO_CTL,
+ BPP_LDO_POWB, BPP_LDO_SUSPEND);
+}
+
+static unsigned int rtl8411_cd_deglitch(struct rtsx_pcr *pcr)
+{
+ unsigned int card_exist;
+
+ card_exist = rtsx_pci_readl(pcr, RTSX_BIPR);
+ card_exist &= CARD_EXIST;
+ if (!card_exist) {
+ /* Enable card CD */
+ rtsx_pci_write_register(pcr, CD_PAD_CTL,
+ CD_DISABLE_MASK, CD_ENABLE);
+ /* Enable card interrupt */
+ rtsx_pci_write_register(pcr, EFUSE_CONTENT, 0xe0, 0x00);
+ return 0;
+ }
+
+ if (hweight32(card_exist) > 1) {
+ rtsx_pci_write_register(pcr, CARD_PWR_CTL,
+ BPP_POWER_MASK, BPP_POWER_5_PERCENT_ON);
+ msleep(100);
+
+ card_exist = rtsx_pci_readl(pcr, RTSX_BIPR);
+ if (card_exist & MS_EXIST)
+ card_exist = MS_EXIST;
+ else if (card_exist & SD_EXIST)
+ card_exist = SD_EXIST;
+ else
+ card_exist = 0;
+
+ rtsx_pci_write_register(pcr, CARD_PWR_CTL,
+ BPP_POWER_MASK, BPP_POWER_OFF);
+
+ dev_dbg(&(pcr->pci->dev),
+ "After CD deglitch, card_exist = 0x%x\n",
+ card_exist);
+ }
+
+ if (card_exist & MS_EXIST) {
+ /* Disable SD interrupt */
+ rtsx_pci_write_register(pcr, EFUSE_CONTENT, 0xe0, 0x40);
+ rtsx_pci_write_register(pcr, CD_PAD_CTL,
+ CD_DISABLE_MASK, MS_CD_EN_ONLY);
+ } else if (card_exist & SD_EXIST) {
+ /* Disable MS interrupt */
+ rtsx_pci_write_register(pcr, EFUSE_CONTENT, 0xe0, 0x80);
+ rtsx_pci_write_register(pcr, CD_PAD_CTL,
+ CD_DISABLE_MASK, SD_CD_EN_ONLY);
+ }
+
+ return card_exist;
+}
+
+static const struct pcr_ops rtl8411_pcr_ops = {
+ .extra_init_hw = rtl8411_extra_init_hw,
+ .optimize_phy = NULL,
+ .turn_on_led = rtl8411_turn_on_led,
+ .turn_off_led = rtl8411_turn_off_led,
+ .enable_auto_blink = rtl8411_enable_auto_blink,
+ .disable_auto_blink = rtl8411_disable_auto_blink,
+ .card_power_on = rtl8411_card_power_on,
+ .card_power_off = rtl8411_card_power_off,
+ .cd_deglitch = rtl8411_cd_deglitch,
+};
+
+/* SD Pull Control Enable:
+ * SD_DAT[3:0] ==> pull up
+ * SD_CD ==> pull up
+ * SD_WP ==> pull up
+ * SD_CMD ==> pull up
+ * SD_CLK ==> pull down
+ */
+static const u32 rtl8411_sd_pull_ctl_enable_tbl[] = {
+ RTSX_REG_PAIR(CARD_PULL_CTL1, 0xAA),
+ RTSX_REG_PAIR(CARD_PULL_CTL2, 0xAA),
+ RTSX_REG_PAIR(CARD_PULL_CTL3, 0xA9),
+ RTSX_REG_PAIR(CARD_PULL_CTL4, 0x09),
+ RTSX_REG_PAIR(CARD_PULL_CTL5, 0x09),
+ RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04),
+ 0,
+};
+
+/* SD Pull Control Disable:
+ * SD_DAT[3:0] ==> pull down
+ * SD_CD ==> pull up
+ * SD_WP ==> pull down
+ * SD_CMD ==> pull down
+ * SD_CLK ==> pull down
+ */
+static const u32 rtl8411_sd_pull_ctl_disable_tbl[] = {
+ RTSX_REG_PAIR(CARD_PULL_CTL1, 0x65),
+ RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
+ RTSX_REG_PAIR(CARD_PULL_CTL3, 0x95),
+ RTSX_REG_PAIR(CARD_PULL_CTL4, 0x09),
+ RTSX_REG_PAIR(CARD_PULL_CTL5, 0x05),
+ RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04),
+ 0,
+};
+
+/* MS Pull Control Enable:
+ * MS CD ==> pull up
+ * others ==> pull down
+ */
+static const u32 rtl8411_ms_pull_ctl_enable_tbl[] = {
+ RTSX_REG_PAIR(CARD_PULL_CTL1, 0x65),
+ RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
+ RTSX_REG_PAIR(CARD_PULL_CTL3, 0x95),
+ RTSX_REG_PAIR(CARD_PULL_CTL4, 0x05),
+ RTSX_REG_PAIR(CARD_PULL_CTL5, 0x05),
+ RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04),
+ 0,
+};
+
+/* MS Pull Control Disable:
+ * MS CD ==> pull up
+ * others ==> pull down
+ */
+static const u32 rtl8411_ms_pull_ctl_disable_tbl[] = {
+ RTSX_REG_PAIR(CARD_PULL_CTL1, 0x65),
+ RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
+ RTSX_REG_PAIR(CARD_PULL_CTL3, 0x95),
+ RTSX_REG_PAIR(CARD_PULL_CTL4, 0x09),
+ RTSX_REG_PAIR(CARD_PULL_CTL5, 0x05),
+ RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04),
+ 0,
+};
+
+void rtl8411_init_params(struct rtsx_pcr *pcr)
+{
+ pcr->extra_caps = EXTRA_CAPS_SD_SDR50 | EXTRA_CAPS_SD_SDR104;
+ pcr->num_slots = 2;
+ pcr->ops = &rtl8411_pcr_ops;
+
+ pcr->ic_version = rtl8411_get_ic_version(pcr);
+ pcr->sd_pull_ctl_enable_tbl = rtl8411_sd_pull_ctl_enable_tbl;
+ pcr->sd_pull_ctl_disable_tbl = rtl8411_sd_pull_ctl_disable_tbl;
+ pcr->ms_pull_ctl_enable_tbl = rtl8411_ms_pull_ctl_enable_tbl;
+ pcr->ms_pull_ctl_disable_tbl = rtl8411_ms_pull_ctl_disable_tbl;
+}
diff --git a/drivers/mfd/rts5209.c b/drivers/mfd/rts5209.c
new file mode 100644
index 000000000000..283a4f148084
--- /dev/null
+++ b/drivers/mfd/rts5209.c
@@ -0,0 +1,223 @@
+/* Driver for Realtek PCI-Express card reader
+ *
+ * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ * Wei WANG <wei_wang@realsil.com.cn>
+ * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/mfd/rtsx_pci.h>
+
+#include "rtsx_pcr.h"
+
+static u8 rts5209_get_ic_version(struct rtsx_pcr *pcr)
+{
+ u8 val;
+
+ val = rtsx_pci_readb(pcr, 0x1C);
+ return val & 0x0F;
+}
+
+static void rts5209_init_vendor_cfg(struct rtsx_pcr *pcr)
+{
+ u32 val;
+
+ rtsx_pci_read_config_dword(pcr, 0x724, &val);
+ dev_dbg(&(pcr->pci->dev), "Cfg 0x724: 0x%x\n", val);
+
+ if (!(val & 0x80)) {
+ if (val & 0x08)
+ pcr->ms_pmos = false;
+ else
+ pcr->ms_pmos = true;
+ }
+}
+
+static int rts5209_extra_init_hw(struct rtsx_pcr *pcr)
+{
+ rtsx_pci_init_cmd(pcr);
+
+ /* Turn off LED */
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_GPIO, 0xFF, 0x03);
+ /* Configure GPIO as output */
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_GPIO_DIR, 0xFF, 0x03);
+
+ return rtsx_pci_send_cmd(pcr, 100);
+}
+
+static int rts5209_optimize_phy(struct rtsx_pcr *pcr)
+{
+ return rtsx_pci_write_phy_register(pcr, 0x00, 0xB966);
+}
+
+static int rts5209_turn_on_led(struct rtsx_pcr *pcr)
+{
+ return rtsx_pci_write_register(pcr, CARD_GPIO, 0x01, 0x00);
+}
+
+static int rts5209_turn_off_led(struct rtsx_pcr *pcr)
+{
+ return rtsx_pci_write_register(pcr, CARD_GPIO, 0x01, 0x01);
+}
+
+static int rts5209_enable_auto_blink(struct rtsx_pcr *pcr)
+{
+ return rtsx_pci_write_register(pcr, CARD_AUTO_BLINK, 0xFF, 0x0D);
+}
+
+static int rts5209_disable_auto_blink(struct rtsx_pcr *pcr)
+{
+ return rtsx_pci_write_register(pcr, CARD_AUTO_BLINK, 0x08, 0x00);
+}
+
+static int rts5209_card_power_on(struct rtsx_pcr *pcr, int card)
+{
+ int err;
+ u8 pwr_mask, partial_pwr_on, pwr_on;
+
+ pwr_mask = SD_POWER_MASK;
+ partial_pwr_on = SD_PARTIAL_POWER_ON;
+ pwr_on = SD_POWER_ON;
+
+ if (pcr->ms_pmos && (card == RTSX_MS_CARD)) {
+ pwr_mask = MS_POWER_MASK;
+ partial_pwr_on = MS_PARTIAL_POWER_ON;
+ pwr_on = MS_POWER_ON;
+ }
+
+ rtsx_pci_init_cmd(pcr);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
+ pwr_mask, partial_pwr_on);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
+ LDO3318_PWR_MASK, 0x04);
+ err = rtsx_pci_send_cmd(pcr, 100);
+ if (err < 0)
+ return err;
+
+ /* To avoid too large in-rush current */
+ udelay(150);
+
+ rtsx_pci_init_cmd(pcr);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL, pwr_mask, pwr_on);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
+ LDO3318_PWR_MASK, 0x00);
+ err = rtsx_pci_send_cmd(pcr, 100);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+
+static int rts5209_card_power_off(struct rtsx_pcr *pcr, int card)
+{
+ u8 pwr_mask, pwr_off;
+
+ pwr_mask = SD_POWER_MASK;
+ pwr_off = SD_POWER_OFF;
+
+ if (pcr->ms_pmos && (card == RTSX_MS_CARD)) {
+ pwr_mask = MS_POWER_MASK;
+ pwr_off = MS_POWER_OFF;
+ }
+
+ rtsx_pci_init_cmd(pcr);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
+ pwr_mask | PMOS_STRG_MASK, pwr_off | PMOS_STRG_400mA);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
+ LDO3318_PWR_MASK, 0X06);
+ return rtsx_pci_send_cmd(pcr, 100);
+}
+
+static const struct pcr_ops rts5209_pcr_ops = {
+ .extra_init_hw = rts5209_extra_init_hw,
+ .optimize_phy = rts5209_optimize_phy,
+ .turn_on_led = rts5209_turn_on_led,
+ .turn_off_led = rts5209_turn_off_led,
+ .enable_auto_blink = rts5209_enable_auto_blink,
+ .disable_auto_blink = rts5209_disable_auto_blink,
+ .card_power_on = rts5209_card_power_on,
+ .card_power_off = rts5209_card_power_off,
+ .cd_deglitch = NULL,
+};
+
+/* SD Pull Control Enable:
+ * SD_DAT[3:0] ==> pull up
+ * SD_CD ==> pull up
+ * SD_WP ==> pull up
+ * SD_CMD ==> pull up
+ * SD_CLK ==> pull down
+ */
+static const u32 rts5209_sd_pull_ctl_enable_tbl[] = {
+ RTSX_REG_PAIR(CARD_PULL_CTL1, 0xAA),
+ RTSX_REG_PAIR(CARD_PULL_CTL2, 0xAA),
+ RTSX_REG_PAIR(CARD_PULL_CTL3, 0xE9),
+ 0,
+};
+
+/* SD Pull Control Disable:
+ * SD_DAT[3:0] ==> pull down
+ * SD_CD ==> pull up
+ * SD_WP ==> pull down
+ * SD_CMD ==> pull down
+ * SD_CLK ==> pull down
+ */
+static const u32 rts5209_sd_pull_ctl_disable_tbl[] = {
+ RTSX_REG_PAIR(CARD_PULL_CTL1, 0x55),
+ RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
+ RTSX_REG_PAIR(CARD_PULL_CTL3, 0xD5),
+ 0,
+};
+
+/* MS Pull Control Enable:
+ * MS CD ==> pull up
+ * others ==> pull down
+ */
+static const u32 rts5209_ms_pull_ctl_enable_tbl[] = {
+ RTSX_REG_PAIR(CARD_PULL_CTL4, 0x55),
+ RTSX_REG_PAIR(CARD_PULL_CTL5, 0x55),
+ RTSX_REG_PAIR(CARD_PULL_CTL6, 0x15),
+ 0,
+};
+
+/* MS Pull Control Disable:
+ * MS CD ==> pull up
+ * others ==> pull down
+ */
+static const u32 rts5209_ms_pull_ctl_disable_tbl[] = {
+ RTSX_REG_PAIR(CARD_PULL_CTL4, 0x55),
+ RTSX_REG_PAIR(CARD_PULL_CTL5, 0x55),
+ RTSX_REG_PAIR(CARD_PULL_CTL6, 0x15),
+ 0,
+};
+
+void rts5209_init_params(struct rtsx_pcr *pcr)
+{
+ pcr->extra_caps = EXTRA_CAPS_SD_SDR50 |
+ EXTRA_CAPS_SD_SDR104 | EXTRA_CAPS_MMC_8BIT;
+ pcr->num_slots = 2;
+ pcr->ops = &rts5209_pcr_ops;
+
+ rts5209_init_vendor_cfg(pcr);
+
+ pcr->ic_version = rts5209_get_ic_version(pcr);
+ pcr->sd_pull_ctl_enable_tbl = rts5209_sd_pull_ctl_enable_tbl;
+ pcr->sd_pull_ctl_disable_tbl = rts5209_sd_pull_ctl_disable_tbl;
+ pcr->ms_pull_ctl_enable_tbl = rts5209_ms_pull_ctl_enable_tbl;
+ pcr->ms_pull_ctl_disable_tbl = rts5209_ms_pull_ctl_disable_tbl;
+}
diff --git a/drivers/mfd/rts5229.c b/drivers/mfd/rts5229.c
new file mode 100644
index 000000000000..b9dbab266fda
--- /dev/null
+++ b/drivers/mfd/rts5229.c
@@ -0,0 +1,205 @@
+/* Driver for Realtek PCI-Express card reader
+ *
+ * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ * Wei WANG <wei_wang@realsil.com.cn>
+ * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/mfd/rtsx_pci.h>
+
+#include "rtsx_pcr.h"
+
+static u8 rts5229_get_ic_version(struct rtsx_pcr *pcr)
+{
+ u8 val;
+
+ rtsx_pci_read_register(pcr, DUMMY_REG_RESET_0, &val);
+ return val & 0x0F;
+}
+
+static int rts5229_extra_init_hw(struct rtsx_pcr *pcr)
+{
+ rtsx_pci_init_cmd(pcr);
+
+ /* Configure GPIO as output */
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, GPIO_CTL, 0x02, 0x02);
+ /* Switch LDO3318 source from DV33 to card_3v3 */
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x00);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x01);
+ /* LED shine disabled, set initial shine cycle period */
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, OLT_LED_CTL, 0x0F, 0x02);
+
+ return rtsx_pci_send_cmd(pcr, 100);
+}
+
+static int rts5229_optimize_phy(struct rtsx_pcr *pcr)
+{
+ /* Optimize RX sensitivity */
+ return rtsx_pci_write_phy_register(pcr, 0x00, 0xBA42);
+}
+
+static int rts5229_turn_on_led(struct rtsx_pcr *pcr)
+{
+ return rtsx_pci_write_register(pcr, GPIO_CTL, 0x02, 0x02);
+}
+
+static int rts5229_turn_off_led(struct rtsx_pcr *pcr)
+{
+ return rtsx_pci_write_register(pcr, GPIO_CTL, 0x02, 0x00);
+}
+
+static int rts5229_enable_auto_blink(struct rtsx_pcr *pcr)
+{
+ return rtsx_pci_write_register(pcr, OLT_LED_CTL, 0x08, 0x08);
+}
+
+static int rts5229_disable_auto_blink(struct rtsx_pcr *pcr)
+{
+ return rtsx_pci_write_register(pcr, OLT_LED_CTL, 0x08, 0x00);
+}
+
+static int rts5229_card_power_on(struct rtsx_pcr *pcr, int card)
+{
+ int err;
+
+ rtsx_pci_init_cmd(pcr);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
+ SD_POWER_MASK, SD_PARTIAL_POWER_ON);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
+ LDO3318_PWR_MASK, 0x02);
+ err = rtsx_pci_send_cmd(pcr, 100);
+ if (err < 0)
+ return err;
+
+ /* To avoid too large in-rush current */
+ udelay(150);
+
+ rtsx_pci_init_cmd(pcr);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
+ SD_POWER_MASK, SD_POWER_ON);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
+ LDO3318_PWR_MASK, 0x06);
+ err = rtsx_pci_send_cmd(pcr, 100);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+
+static int rts5229_card_power_off(struct rtsx_pcr *pcr, int card)
+{
+ rtsx_pci_init_cmd(pcr);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
+ SD_POWER_MASK | PMOS_STRG_MASK,
+ SD_POWER_OFF | PMOS_STRG_400mA);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
+ LDO3318_PWR_MASK, 0X00);
+ return rtsx_pci_send_cmd(pcr, 100);
+}
+
+static const struct pcr_ops rts5229_pcr_ops = {
+ .extra_init_hw = rts5229_extra_init_hw,
+ .optimize_phy = rts5229_optimize_phy,
+ .turn_on_led = rts5229_turn_on_led,
+ .turn_off_led = rts5229_turn_off_led,
+ .enable_auto_blink = rts5229_enable_auto_blink,
+ .disable_auto_blink = rts5229_disable_auto_blink,
+ .card_power_on = rts5229_card_power_on,
+ .card_power_off = rts5229_card_power_off,
+ .cd_deglitch = NULL,
+};
+
+/* SD Pull Control Enable:
+ * SD_DAT[3:0] ==> pull up
+ * SD_CD ==> pull up
+ * SD_WP ==> pull up
+ * SD_CMD ==> pull up
+ * SD_CLK ==> pull down
+ */
+static const u32 rts5229_sd_pull_ctl_enable_tbl1[] = {
+ RTSX_REG_PAIR(CARD_PULL_CTL2, 0xAA),
+ RTSX_REG_PAIR(CARD_PULL_CTL3, 0xE9),
+ 0,
+};
+
+/* For RTS5229 version C */
+static const u32 rts5229_sd_pull_ctl_enable_tbl2[] = {
+ RTSX_REG_PAIR(CARD_PULL_CTL2, 0xAA),
+ RTSX_REG_PAIR(CARD_PULL_CTL3, 0xD9),
+ 0,
+};
+
+/* SD Pull Control Disable:
+ * SD_DAT[3:0] ==> pull down
+ * SD_CD ==> pull up
+ * SD_WP ==> pull down
+ * SD_CMD ==> pull down
+ * SD_CLK ==> pull down
+ */
+static const u32 rts5229_sd_pull_ctl_disable_tbl1[] = {
+ RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
+ RTSX_REG_PAIR(CARD_PULL_CTL3, 0xD5),
+ 0,
+};
+
+/* For RTS5229 version C */
+static const u32 rts5229_sd_pull_ctl_disable_tbl2[] = {
+ RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
+ RTSX_REG_PAIR(CARD_PULL_CTL3, 0xE5),
+ 0,
+};
+
+/* MS Pull Control Enable:
+ * MS CD ==> pull up
+ * others ==> pull down
+ */
+static const u32 rts5229_ms_pull_ctl_enable_tbl[] = {
+ RTSX_REG_PAIR(CARD_PULL_CTL5, 0x55),
+ RTSX_REG_PAIR(CARD_PULL_CTL6, 0x15),
+ 0,
+};
+
+/* MS Pull Control Disable:
+ * MS CD ==> pull up
+ * others ==> pull down
+ */
+static const u32 rts5229_ms_pull_ctl_disable_tbl[] = {
+ RTSX_REG_PAIR(CARD_PULL_CTL5, 0x55),
+ RTSX_REG_PAIR(CARD_PULL_CTL6, 0x15),
+ 0,
+};
+
+void rts5229_init_params(struct rtsx_pcr *pcr)
+{
+ pcr->extra_caps = EXTRA_CAPS_SD_SDR50 | EXTRA_CAPS_SD_SDR104;
+ pcr->num_slots = 2;
+ pcr->ops = &rts5229_pcr_ops;
+
+ pcr->ic_version = rts5229_get_ic_version(pcr);
+ if (pcr->ic_version == IC_VER_C) {
+ pcr->sd_pull_ctl_enable_tbl = rts5229_sd_pull_ctl_enable_tbl2;
+ pcr->sd_pull_ctl_disable_tbl = rts5229_sd_pull_ctl_disable_tbl2;
+ } else {
+ pcr->sd_pull_ctl_enable_tbl = rts5229_sd_pull_ctl_enable_tbl1;
+ pcr->sd_pull_ctl_disable_tbl = rts5229_sd_pull_ctl_disable_tbl1;
+ }
+ pcr->ms_pull_ctl_enable_tbl = rts5229_ms_pull_ctl_enable_tbl;
+ pcr->ms_pull_ctl_disable_tbl = rts5229_ms_pull_ctl_disable_tbl;
+}
diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c
new file mode 100644
index 000000000000..56d4377c62c2
--- /dev/null
+++ b/drivers/mfd/rtsx_pcr.c
@@ -0,0 +1,1251 @@
+/* Driver for Realtek PCI-Express card reader
+ *
+ * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ * Wei WANG <wei_wang@realsil.com.cn>
+ * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
+ */
+
+#include <linux/pci.h>
+#include <linux/module.h>
+#include <linux/dma-mapping.h>
+#include <linux/highmem.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/idr.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/rtsx_pci.h>
+#include <asm/unaligned.h>
+
+#include "rtsx_pcr.h"
+
+static bool msi_en = true;
+module_param(msi_en, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(msi_en, "Enable MSI");
+
+static DEFINE_IDR(rtsx_pci_idr);
+static DEFINE_SPINLOCK(rtsx_pci_lock);
+
+static struct mfd_cell rtsx_pcr_cells[] = {
+ [RTSX_SD_CARD] = {
+ .name = DRV_NAME_RTSX_PCI_SDMMC,
+ },
+ [RTSX_MS_CARD] = {
+ .name = DRV_NAME_RTSX_PCI_MS,
+ },
+};
+
+static DEFINE_PCI_DEVICE_TABLE(rtsx_pci_ids) = {
+ { PCI_DEVICE(0x10EC, 0x5209), PCI_CLASS_OTHERS << 16, 0xFF0000 },
+ { PCI_DEVICE(0x10EC, 0x5229), PCI_CLASS_OTHERS << 16, 0xFF0000 },
+ { PCI_DEVICE(0x10EC, 0x5289), PCI_CLASS_OTHERS << 16, 0xFF0000 },
+ { 0, }
+};
+
+MODULE_DEVICE_TABLE(pci, rtsx_pci_ids);
+
+void rtsx_pci_start_run(struct rtsx_pcr *pcr)
+{
+ /* If pci device removed, don't queue idle work any more */
+ if (pcr->remove_pci)
+ return;
+
+ if (pcr->state != PDEV_STAT_RUN) {
+ pcr->state = PDEV_STAT_RUN;
+ if (pcr->ops->enable_auto_blink)
+ pcr->ops->enable_auto_blink(pcr);
+ }
+
+ mod_delayed_work(system_wq, &pcr->idle_work, msecs_to_jiffies(200));
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_start_run);
+
+int rtsx_pci_write_register(struct rtsx_pcr *pcr, u16 addr, u8 mask, u8 data)
+{
+ int i;
+ u32 val = HAIMR_WRITE_START;
+
+ val |= (u32)(addr & 0x3FFF) << 16;
+ val |= (u32)mask << 8;
+ val |= (u32)data;
+
+ rtsx_pci_writel(pcr, RTSX_HAIMR, val);
+
+ for (i = 0; i < MAX_RW_REG_CNT; i++) {
+ val = rtsx_pci_readl(pcr, RTSX_HAIMR);
+ if ((val & HAIMR_TRANS_END) == 0) {
+ if (data != (u8)val)
+ return -EIO;
+ return 0;
+ }
+ }
+
+ return -ETIMEDOUT;
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_write_register);
+
+int rtsx_pci_read_register(struct rtsx_pcr *pcr, u16 addr, u8 *data)
+{
+ u32 val = HAIMR_READ_START;
+ int i;
+
+ val |= (u32)(addr & 0x3FFF) << 16;
+ rtsx_pci_writel(pcr, RTSX_HAIMR, val);
+
+ for (i = 0; i < MAX_RW_REG_CNT; i++) {
+ val = rtsx_pci_readl(pcr, RTSX_HAIMR);
+ if ((val & HAIMR_TRANS_END) == 0)
+ break;
+ }
+
+ if (i >= MAX_RW_REG_CNT)
+ return -ETIMEDOUT;
+
+ if (data)
+ *data = (u8)(val & 0xFF);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_read_register);
+
+int rtsx_pci_write_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 val)
+{
+ int err, i, finished = 0;
+ u8 tmp;
+
+ rtsx_pci_init_cmd(pcr);
+
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PHYDATA0, 0xFF, (u8)val);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PHYDATA1, 0xFF, (u8)(val >> 8));
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PHYADDR, 0xFF, addr);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PHYRWCTL, 0xFF, 0x81);
+
+ err = rtsx_pci_send_cmd(pcr, 100);
+ if (err < 0)
+ return err;
+
+ for (i = 0; i < 100000; i++) {
+ err = rtsx_pci_read_register(pcr, PHYRWCTL, &tmp);
+ if (err < 0)
+ return err;
+
+ if (!(tmp & 0x80)) {
+ finished = 1;
+ break;
+ }
+ }
+
+ if (!finished)
+ return -ETIMEDOUT;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_write_phy_register);
+
+int rtsx_pci_read_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 *val)
+{
+ int err, i, finished = 0;
+ u16 data;
+ u8 *ptr, tmp;
+
+ rtsx_pci_init_cmd(pcr);
+
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PHYADDR, 0xFF, addr);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PHYRWCTL, 0xFF, 0x80);
+
+ err = rtsx_pci_send_cmd(pcr, 100);
+ if (err < 0)
+ return err;
+
+ for (i = 0; i < 100000; i++) {
+ err = rtsx_pci_read_register(pcr, PHYRWCTL, &tmp);
+ if (err < 0)
+ return err;
+
+ if (!(tmp & 0x80)) {
+ finished = 1;
+ break;
+ }
+ }
+
+ if (!finished)
+ return -ETIMEDOUT;
+
+ rtsx_pci_init_cmd(pcr);
+
+ rtsx_pci_add_cmd(pcr, READ_REG_CMD, PHYDATA0, 0, 0);
+ rtsx_pci_add_cmd(pcr, READ_REG_CMD, PHYDATA1, 0, 0);
+
+ err = rtsx_pci_send_cmd(pcr, 100);
+ if (err < 0)
+ return err;
+
+ ptr = rtsx_pci_get_cmd_data(pcr);
+ data = ((u16)ptr[1] << 8) | ptr[0];
+
+ if (val)
+ *val = data;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_read_phy_register);
+
+void rtsx_pci_stop_cmd(struct rtsx_pcr *pcr)
+{
+ rtsx_pci_writel(pcr, RTSX_HCBCTLR, STOP_CMD);
+ rtsx_pci_writel(pcr, RTSX_HDBCTLR, STOP_DMA);
+
+ rtsx_pci_write_register(pcr, DMACTL, 0x80, 0x80);
+ rtsx_pci_write_register(pcr, RBCTL, 0x80, 0x80);
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_stop_cmd);
+
+void rtsx_pci_add_cmd(struct rtsx_pcr *pcr,
+ u8 cmd_type, u16 reg_addr, u8 mask, u8 data)
+{
+ unsigned long flags;
+ u32 val = 0;
+ u32 *ptr = (u32 *)(pcr->host_cmds_ptr);
+
+ val |= (u32)(cmd_type & 0x03) << 30;
+ val |= (u32)(reg_addr & 0x3FFF) << 16;
+ val |= (u32)mask << 8;
+ val |= (u32)data;
+
+ spin_lock_irqsave(&pcr->lock, flags);
+ ptr += pcr->ci;
+ if (pcr->ci < (HOST_CMDS_BUF_LEN / 4)) {
+ put_unaligned_le32(val, ptr);
+ ptr++;
+ pcr->ci++;
+ }
+ spin_unlock_irqrestore(&pcr->lock, flags);
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_add_cmd);
+
+void rtsx_pci_send_cmd_no_wait(struct rtsx_pcr *pcr)
+{
+ u32 val = 1 << 31;
+
+ rtsx_pci_writel(pcr, RTSX_HCBAR, pcr->host_cmds_addr);
+
+ val |= (u32)(pcr->ci * 4) & 0x00FFFFFF;
+ /* Hardware Auto Response */
+ val |= 0x40000000;
+ rtsx_pci_writel(pcr, RTSX_HCBCTLR, val);
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_send_cmd_no_wait);
+
+int rtsx_pci_send_cmd(struct rtsx_pcr *pcr, int timeout)
+{
+ struct completion trans_done;
+ u32 val = 1 << 31;
+ long timeleft;
+ unsigned long flags;
+ int err = 0;
+
+ spin_lock_irqsave(&pcr->lock, flags);
+
+ /* set up data structures for the wakeup system */
+ pcr->done = &trans_done;
+ pcr->trans_result = TRANS_NOT_READY;
+ init_completion(&trans_done);
+
+ rtsx_pci_writel(pcr, RTSX_HCBAR, pcr->host_cmds_addr);
+
+ val |= (u32)(pcr->ci * 4) & 0x00FFFFFF;
+ /* Hardware Auto Response */
+ val |= 0x40000000;
+ rtsx_pci_writel(pcr, RTSX_HCBCTLR, val);
+
+ spin_unlock_irqrestore(&pcr->lock, flags);
+
+ /* Wait for TRANS_OK_INT */
+ timeleft = wait_for_completion_interruptible_timeout(
+ &trans_done, msecs_to_jiffies(timeout));
+ if (timeleft <= 0) {
+ dev_dbg(&(pcr->pci->dev), "Timeout (%s %d)\n",
+ __func__, __LINE__);
+ err = -ETIMEDOUT;
+ goto finish_send_cmd;
+ }
+
+ spin_lock_irqsave(&pcr->lock, flags);
+ if (pcr->trans_result == TRANS_RESULT_FAIL)
+ err = -EINVAL;
+ else if (pcr->trans_result == TRANS_RESULT_OK)
+ err = 0;
+ else if (pcr->trans_result == TRANS_NO_DEVICE)
+ err = -ENODEV;
+ spin_unlock_irqrestore(&pcr->lock, flags);
+
+finish_send_cmd:
+ spin_lock_irqsave(&pcr->lock, flags);
+ pcr->done = NULL;
+ spin_unlock_irqrestore(&pcr->lock, flags);
+
+ if ((err < 0) && (err != -ENODEV))
+ rtsx_pci_stop_cmd(pcr);
+
+ if (pcr->finish_me)
+ complete(pcr->finish_me);
+
+ return err;
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_send_cmd);
+
+static void rtsx_pci_add_sg_tbl(struct rtsx_pcr *pcr,
+ dma_addr_t addr, unsigned int len, int end)
+{
+ u64 *ptr = (u64 *)(pcr->host_sg_tbl_ptr) + pcr->sgi;
+ u64 val;
+ u8 option = SG_VALID | SG_TRANS_DATA;
+
+ dev_dbg(&(pcr->pci->dev), "DMA addr: 0x%x, Len: 0x%x\n",
+ (unsigned int)addr, len);
+
+ if (end)
+ option |= SG_END;
+ val = ((u64)addr << 32) | ((u64)len << 12) | option;
+
+ put_unaligned_le64(val, ptr);
+ ptr++;
+ pcr->sgi++;
+}
+
+int rtsx_pci_transfer_data(struct rtsx_pcr *pcr, struct scatterlist *sglist,
+ int num_sg, bool read, int timeout)
+{
+ struct completion trans_done;
+ u8 dir;
+ int err = 0, i, count;
+ long timeleft;
+ unsigned long flags;
+ struct scatterlist *sg;
+ enum dma_data_direction dma_dir;
+ u32 val;
+ dma_addr_t addr;
+ unsigned int len;
+
+ dev_dbg(&(pcr->pci->dev), "--> %s: num_sg = %d\n", __func__, num_sg);
+
+ /* don't transfer data during abort processing */
+ if (pcr->remove_pci)
+ return -EINVAL;
+
+ if ((sglist == NULL) || (num_sg <= 0))
+ return -EINVAL;
+
+ if (read) {
+ dir = DEVICE_TO_HOST;
+ dma_dir = DMA_FROM_DEVICE;
+ } else {
+ dir = HOST_TO_DEVICE;
+ dma_dir = DMA_TO_DEVICE;
+ }
+
+ count = dma_map_sg(&(pcr->pci->dev), sglist, num_sg, dma_dir);
+ if (count < 1) {
+ dev_err(&(pcr->pci->dev), "scatterlist map failed\n");
+ return -EINVAL;
+ }
+ dev_dbg(&(pcr->pci->dev), "DMA mapping count: %d\n", count);
+
+ val = ((u32)(dir & 0x01) << 29) | TRIG_DMA | ADMA_MODE;
+ pcr->sgi = 0;
+ for_each_sg(sglist, sg, count, i) {
+ addr = sg_dma_address(sg);
+ len = sg_dma_len(sg);
+ rtsx_pci_add_sg_tbl(pcr, addr, len, i == count - 1);
+ }
+
+ spin_lock_irqsave(&pcr->lock, flags);
+
+ pcr->done = &trans_done;
+ pcr->trans_result = TRANS_NOT_READY;
+ init_completion(&trans_done);
+ rtsx_pci_writel(pcr, RTSX_HDBAR, pcr->host_sg_tbl_addr);
+ rtsx_pci_writel(pcr, RTSX_HDBCTLR, val);
+
+ spin_unlock_irqrestore(&pcr->lock, flags);
+
+ timeleft = wait_for_completion_interruptible_timeout(
+ &trans_done, msecs_to_jiffies(timeout));
+ if (timeleft <= 0) {
+ dev_dbg(&(pcr->pci->dev), "Timeout (%s %d)\n",
+ __func__, __LINE__);
+ err = -ETIMEDOUT;
+ goto out;
+ }
+
+ spin_lock_irqsave(&pcr->lock, flags);
+
+ if (pcr->trans_result == TRANS_RESULT_FAIL)
+ err = -EINVAL;
+ else if (pcr->trans_result == TRANS_NO_DEVICE)
+ err = -ENODEV;
+
+ spin_unlock_irqrestore(&pcr->lock, flags);
+
+out:
+ spin_lock_irqsave(&pcr->lock, flags);
+ pcr->done = NULL;
+ spin_unlock_irqrestore(&pcr->lock, flags);
+
+ dma_unmap_sg(&(pcr->pci->dev), sglist, num_sg, dma_dir);
+
+ if ((err < 0) && (err != -ENODEV))
+ rtsx_pci_stop_cmd(pcr);
+
+ if (pcr->finish_me)
+ complete(pcr->finish_me);
+
+ return err;
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_transfer_data);
+
+int rtsx_pci_read_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len)
+{
+ int err;
+ int i, j;
+ u16 reg;
+ u8 *ptr;
+
+ if (buf_len > 512)
+ buf_len = 512;
+
+ ptr = buf;
+ reg = PPBUF_BASE2;
+ for (i = 0; i < buf_len / 256; i++) {
+ rtsx_pci_init_cmd(pcr);
+
+ for (j = 0; j < 256; j++)
+ rtsx_pci_add_cmd(pcr, READ_REG_CMD, reg++, 0, 0);
+
+ err = rtsx_pci_send_cmd(pcr, 250);
+ if (err < 0)
+ return err;
+
+ memcpy(ptr, rtsx_pci_get_cmd_data(pcr), 256);
+ ptr += 256;
+ }
+
+ if (buf_len % 256) {
+ rtsx_pci_init_cmd(pcr);
+
+ for (j = 0; j < buf_len % 256; j++)
+ rtsx_pci_add_cmd(pcr, READ_REG_CMD, reg++, 0, 0);
+
+ err = rtsx_pci_send_cmd(pcr, 250);
+ if (err < 0)
+ return err;
+ }
+
+ memcpy(ptr, rtsx_pci_get_cmd_data(pcr), buf_len % 256);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_read_ppbuf);
+
+int rtsx_pci_write_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len)
+{
+ int err;
+ int i, j;
+ u16 reg;
+ u8 *ptr;
+
+ if (buf_len > 512)
+ buf_len = 512;
+
+ ptr = buf;
+ reg = PPBUF_BASE2;
+ for (i = 0; i < buf_len / 256; i++) {
+ rtsx_pci_init_cmd(pcr);
+
+ for (j = 0; j < 256; j++) {
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
+ reg++, 0xFF, *ptr);
+ ptr++;
+ }
+
+ err = rtsx_pci_send_cmd(pcr, 250);
+ if (err < 0)
+ return err;
+ }
+
+ if (buf_len % 256) {
+ rtsx_pci_init_cmd(pcr);
+
+ for (j = 0; j < buf_len % 256; j++) {
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
+ reg++, 0xFF, *ptr);
+ ptr++;
+ }
+
+ err = rtsx_pci_send_cmd(pcr, 250);
+ if (err < 0)
+ return err;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_write_ppbuf);
+
+static int rtsx_pci_set_pull_ctl(struct rtsx_pcr *pcr, const u32 *tbl)
+{
+ int err;
+
+ rtsx_pci_init_cmd(pcr);
+
+ while (*tbl & 0xFFFF0000) {
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
+ (u16)(*tbl >> 16), 0xFF, (u8)(*tbl));
+ tbl++;
+ }
+
+ err = rtsx_pci_send_cmd(pcr, 100);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+
+int rtsx_pci_card_pull_ctl_enable(struct rtsx_pcr *pcr, int card)
+{
+ const u32 *tbl;
+
+ if (card == RTSX_SD_CARD)
+ tbl = pcr->sd_pull_ctl_enable_tbl;
+ else if (card == RTSX_MS_CARD)
+ tbl = pcr->ms_pull_ctl_enable_tbl;
+ else
+ return -EINVAL;
+
+ return rtsx_pci_set_pull_ctl(pcr, tbl);
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_card_pull_ctl_enable);
+
+int rtsx_pci_card_pull_ctl_disable(struct rtsx_pcr *pcr, int card)
+{
+ const u32 *tbl;
+
+ if (card == RTSX_SD_CARD)
+ tbl = pcr->sd_pull_ctl_disable_tbl;
+ else if (card == RTSX_MS_CARD)
+ tbl = pcr->ms_pull_ctl_disable_tbl;
+ else
+ return -EINVAL;
+
+
+ return rtsx_pci_set_pull_ctl(pcr, tbl);
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_card_pull_ctl_disable);
+
+static void rtsx_pci_enable_bus_int(struct rtsx_pcr *pcr)
+{
+ pcr->bier = TRANS_OK_INT_EN | TRANS_FAIL_INT_EN | SD_INT_EN;
+
+ if (pcr->num_slots > 1)
+ pcr->bier |= MS_INT_EN;
+
+ /* Enable Bus Interrupt */
+ rtsx_pci_writel(pcr, RTSX_BIER, pcr->bier);
+
+ dev_dbg(&(pcr->pci->dev), "RTSX_BIER: 0x%08x\n", pcr->bier);
+}
+
+static inline u8 double_ssc_depth(u8 depth)
+{
+ return ((depth > 1) ? (depth - 1) : depth);
+}
+
+static u8 revise_ssc_depth(u8 ssc_depth, u8 div)
+{
+ if (div > CLK_DIV_1) {
+ if (ssc_depth > (div - 1))
+ ssc_depth -= (div - 1);
+ else
+ ssc_depth = SSC_DEPTH_4M;
+ }
+
+ return ssc_depth;
+}
+
+int rtsx_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock,
+ u8 ssc_depth, bool initial_mode, bool double_clk, bool vpclk)
+{
+ int err, clk;
+ u8 N, min_N, max_N, clk_divider;
+ u8 mcu_cnt, div, max_div;
+ u8 depth[] = {
+ [RTSX_SSC_DEPTH_4M] = SSC_DEPTH_4M,
+ [RTSX_SSC_DEPTH_2M] = SSC_DEPTH_2M,
+ [RTSX_SSC_DEPTH_1M] = SSC_DEPTH_1M,
+ [RTSX_SSC_DEPTH_500K] = SSC_DEPTH_500K,
+ [RTSX_SSC_DEPTH_250K] = SSC_DEPTH_250K,
+ };
+
+ if (initial_mode) {
+ /* We use 250k(around) here, in initial stage */
+ clk_divider = SD_CLK_DIVIDE_128;
+ card_clock = 30000000;
+ } else {
+ clk_divider = SD_CLK_DIVIDE_0;
+ }
+ err = rtsx_pci_write_register(pcr, SD_CFG1,
+ SD_CLK_DIVIDE_MASK, clk_divider);
+ if (err < 0)
+ return err;
+
+ card_clock /= 1000000;
+ dev_dbg(&(pcr->pci->dev), "Switch card clock to %dMHz\n", card_clock);
+
+ min_N = 80;
+ max_N = 208;
+ max_div = CLK_DIV_8;
+
+ clk = card_clock;
+ if (!initial_mode && double_clk)
+ clk = card_clock * 2;
+ dev_dbg(&(pcr->pci->dev),
+ "Internal SSC clock: %dMHz (cur_clock = %d)\n",
+ clk, pcr->cur_clock);
+
+ if (clk == pcr->cur_clock)
+ return 0;
+
+ N = (u8)(clk - 2);
+ if ((clk <= 2) || (N > max_N))
+ return -EINVAL;
+
+ mcu_cnt = (u8)(125/clk + 3);
+ if (mcu_cnt > 15)
+ mcu_cnt = 15;
+
+ /* Make sure that the SSC clock div_n is equal or greater than min_N */
+ div = CLK_DIV_1;
+ while ((N < min_N) && (div < max_div)) {
+ N = (N + 2) * 2 - 2;
+ div++;
+ }
+ dev_dbg(&(pcr->pci->dev), "N = %d, div = %d\n", N, div);
+
+ ssc_depth = depth[ssc_depth];
+ if (double_clk)
+ ssc_depth = double_ssc_depth(ssc_depth);
+
+ ssc_depth = revise_ssc_depth(ssc_depth, div);
+ dev_dbg(&(pcr->pci->dev), "ssc_depth = %d\n", ssc_depth);
+
+ rtsx_pci_init_cmd(pcr);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_CTL,
+ CLK_LOW_FREQ, CLK_LOW_FREQ);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_DIV,
+ 0xFF, (div << 4) | mcu_cnt);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, 0);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL2,
+ SSC_DEPTH_MASK, ssc_depth);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_DIV_N_0, 0xFF, N);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, SSC_RSTB);
+ if (vpclk) {
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_VPCLK0_CTL,
+ PHASE_NOT_RESET, 0);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_VPCLK0_CTL,
+ PHASE_NOT_RESET, PHASE_NOT_RESET);
+ }
+
+ err = rtsx_pci_send_cmd(pcr, 2000);
+ if (err < 0)
+ return err;
+
+ /* Wait SSC clock stable */
+ udelay(10);
+ err = rtsx_pci_write_register(pcr, CLK_CTL, CLK_LOW_FREQ, 0);
+ if (err < 0)
+ return err;
+
+ pcr->cur_clock = clk;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_switch_clock);
+
+int rtsx_pci_card_power_on(struct rtsx_pcr *pcr, int card)
+{
+ if (pcr->ops->card_power_on)
+ return pcr->ops->card_power_on(pcr, card);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_card_power_on);
+
+int rtsx_pci_card_power_off(struct rtsx_pcr *pcr, int card)
+{
+ if (pcr->ops->card_power_off)
+ return pcr->ops->card_power_off(pcr, card);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_card_power_off);
+
+unsigned int rtsx_pci_card_exist(struct rtsx_pcr *pcr)
+{
+ unsigned int val;
+
+ val = rtsx_pci_readl(pcr, RTSX_BIPR);
+ if (pcr->ops->cd_deglitch)
+ val = pcr->ops->cd_deglitch(pcr);
+
+ return val;
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_card_exist);
+
+void rtsx_pci_complete_unfinished_transfer(struct rtsx_pcr *pcr)
+{
+ struct completion finish;
+
+ pcr->finish_me = &finish;
+ init_completion(&finish);
+
+ if (pcr->done)
+ complete(pcr->done);
+
+ if (!pcr->remove_pci)
+ rtsx_pci_stop_cmd(pcr);
+
+ wait_for_completion_interruptible_timeout(&finish,
+ msecs_to_jiffies(2));
+ pcr->finish_me = NULL;
+}
+EXPORT_SYMBOL_GPL(rtsx_pci_complete_unfinished_transfer);
+
+static void rtsx_pci_card_detect(struct work_struct *work)
+{
+ struct delayed_work *dwork;
+ struct rtsx_pcr *pcr;
+ unsigned long flags;
+ unsigned int card_detect = 0;
+ u32 irq_status;
+
+ dwork = to_delayed_work(work);
+ pcr = container_of(dwork, struct rtsx_pcr, carddet_work);
+
+ dev_dbg(&(pcr->pci->dev), "--> %s\n", __func__);
+
+ spin_lock_irqsave(&pcr->lock, flags);
+
+ irq_status = rtsx_pci_readl(pcr, RTSX_BIPR);
+ dev_dbg(&(pcr->pci->dev), "irq_status: 0x%08x\n", irq_status);
+
+ if (pcr->card_inserted || pcr->card_removed) {
+ dev_dbg(&(pcr->pci->dev),
+ "card_inserted: 0x%x, card_removed: 0x%x\n",
+ pcr->card_inserted, pcr->card_removed);
+
+ if (pcr->ops->cd_deglitch)
+ pcr->card_inserted = pcr->ops->cd_deglitch(pcr);
+
+ card_detect = pcr->card_inserted | pcr->card_removed;
+ pcr->card_inserted = 0;
+ pcr->card_removed = 0;
+ }
+
+ spin_unlock_irqrestore(&pcr->lock, flags);
+
+ if (card_detect & SD_EXIST)
+ pcr->slots[RTSX_SD_CARD].card_event(
+ pcr->slots[RTSX_SD_CARD].p_dev);
+ if (card_detect & MS_EXIST)
+ pcr->slots[RTSX_MS_CARD].card_event(
+ pcr->slots[RTSX_MS_CARD].p_dev);
+}
+
+static irqreturn_t rtsx_pci_isr(int irq, void *dev_id)
+{
+ struct rtsx_pcr *pcr = dev_id;
+ u32 int_reg;
+
+ if (!pcr)
+ return IRQ_NONE;
+
+ spin_lock(&pcr->lock);
+
+ int_reg = rtsx_pci_readl(pcr, RTSX_BIPR);
+ /* Clear interrupt flag */
+ rtsx_pci_writel(pcr, RTSX_BIPR, int_reg);
+ if ((int_reg & pcr->bier) == 0) {
+ spin_unlock(&pcr->lock);
+ return IRQ_NONE;
+ }
+ if (int_reg == 0xFFFFFFFF) {
+ spin_unlock(&pcr->lock);
+ return IRQ_HANDLED;
+ }
+
+ int_reg &= (pcr->bier | 0x7FFFFF);
+
+ if (int_reg & SD_INT) {
+ if (int_reg & SD_EXIST) {
+ pcr->card_inserted |= SD_EXIST;
+ } else {
+ pcr->card_removed |= SD_EXIST;
+ pcr->card_inserted &= ~SD_EXIST;
+ }
+ }
+
+ if (int_reg & MS_INT) {
+ if (int_reg & MS_EXIST) {
+ pcr->card_inserted |= MS_EXIST;
+ } else {
+ pcr->card_removed |= MS_EXIST;
+ pcr->card_inserted &= ~MS_EXIST;
+ }
+ }
+
+ if (pcr->card_inserted || pcr->card_removed)
+ schedule_delayed_work(&pcr->carddet_work,
+ msecs_to_jiffies(200));
+
+ if (int_reg & (NEED_COMPLETE_INT | DELINK_INT)) {
+ if (int_reg & (TRANS_FAIL_INT | DELINK_INT)) {
+ pcr->trans_result = TRANS_RESULT_FAIL;
+ if (pcr->done)
+ complete(pcr->done);
+ } else if (int_reg & TRANS_OK_INT) {
+ pcr->trans_result = TRANS_RESULT_OK;
+ if (pcr->done)
+ complete(pcr->done);
+ }
+ }
+
+ spin_unlock(&pcr->lock);
+ return IRQ_HANDLED;
+}
+
+static int rtsx_pci_acquire_irq(struct rtsx_pcr *pcr)
+{
+ dev_info(&(pcr->pci->dev), "%s: pcr->msi_en = %d, pci->irq = %d\n",
+ __func__, pcr->msi_en, pcr->pci->irq);
+
+ if (request_irq(pcr->pci->irq, rtsx_pci_isr,
+ pcr->msi_en ? 0 : IRQF_SHARED,
+ DRV_NAME_RTSX_PCI, pcr)) {
+ dev_err(&(pcr->pci->dev),
+ "rtsx_sdmmc: unable to grab IRQ %d, disabling device\n",
+ pcr->pci->irq);
+ return -1;
+ }
+
+ pcr->irq = pcr->pci->irq;
+ pci_intx(pcr->pci, !pcr->msi_en);
+
+ return 0;
+}
+
+static void rtsx_pci_idle_work(struct work_struct *work)
+{
+ struct delayed_work *dwork = to_delayed_work(work);
+ struct rtsx_pcr *pcr = container_of(dwork, struct rtsx_pcr, idle_work);
+
+ dev_dbg(&(pcr->pci->dev), "--> %s\n", __func__);
+
+ mutex_lock(&pcr->pcr_mutex);
+
+ pcr->state = PDEV_STAT_IDLE;
+
+ if (pcr->ops->disable_auto_blink)
+ pcr->ops->disable_auto_blink(pcr);
+ if (pcr->ops->turn_off_led)
+ pcr->ops->turn_off_led(pcr);
+
+ mutex_unlock(&pcr->pcr_mutex);
+}
+
+static int rtsx_pci_init_hw(struct rtsx_pcr *pcr)
+{
+ int err;
+
+ rtsx_pci_writel(pcr, RTSX_HCBAR, pcr->host_cmds_addr);
+
+ rtsx_pci_enable_bus_int(pcr);
+
+ /* Power on SSC */
+ err = rtsx_pci_write_register(pcr, FPDCTL, SSC_POWER_DOWN, 0);
+ if (err < 0)
+ return err;
+
+ /* Wait SSC power stable */
+ udelay(200);
+
+ if (pcr->ops->optimize_phy) {
+ err = pcr->ops->optimize_phy(pcr);
+ if (err < 0)
+ return err;
+ }
+
+ rtsx_pci_init_cmd(pcr);
+
+ /* Set mcu_cnt to 7 to ensure data can be sampled properly */
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_DIV, 0x07, 0x07);
+
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, HOST_SLEEP_STATE, 0x03, 0x00);
+ /* Disable card clock */
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_CLK_EN, 0x1E, 0);
+ /* Reset ASPM state to default value */
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, ASPM_FORCE_CTL, 0x3F, 0);
+ /* Reset delink mode */
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CHANGE_LINK_STATE, 0x0A, 0);
+ /* Card driving select */
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DRIVE_SEL,
+ 0x07, DRIVER_TYPE_D);
+ /* Enable SSC Clock */
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL1,
+ 0xFF, SSC_8X_EN | SSC_SEL_4M);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL2, 0xFF, 0x12);
+ /* Disable cd_pwr_save */
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CHANGE_LINK_STATE, 0x16, 0x10);
+ /* Clear Link Ready Interrupt */
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, IRQSTAT0,
+ LINK_RDY_INT, LINK_RDY_INT);
+ /* Enlarge the estimation window of PERST# glitch
+ * to reduce the chance of invalid card interrupt
+ */
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PERST_GLITCH_WIDTH, 0xFF, 0x80);
+ /* Update RC oscillator to 400k
+ * bit[0] F_HIGH: for RC oscillator, Rst_value is 1'b1
+ * 1: 2M 0: 400k
+ */
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, RCCTL, 0x01, 0x00);
+ /* Set interrupt write clear
+ * bit 1: U_elbi_if_rd_clr_en
+ * 1: Enable ELBI interrupt[31:22] & [7:0] flag read clear
+ * 0: ELBI interrupt flag[31:22] & [7:0] only can be write clear
+ */
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, NFTS_TX_CTRL, 0x02, 0);
+ /* Force CLKREQ# PIN to drive 0 to request clock */
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0x08, 0x08);
+
+ err = rtsx_pci_send_cmd(pcr, 100);
+ if (err < 0)
+ return err;
+
+ /* Enable clk_request_n to enable clock power management */
+ rtsx_pci_write_config_byte(pcr, 0x81, 1);
+ /* Enter L1 when host tx idle */
+ rtsx_pci_write_config_byte(pcr, 0x70F, 0x5B);
+
+ if (pcr->ops->extra_init_hw) {
+ err = pcr->ops->extra_init_hw(pcr);
+ if (err < 0)
+ return err;
+ }
+
+ return 0;
+}
+
+static int rtsx_pci_init_chip(struct rtsx_pcr *pcr)
+{
+ int err;
+
+ spin_lock_init(&pcr->lock);
+ mutex_init(&pcr->pcr_mutex);
+
+ switch (PCI_PID(pcr)) {
+ default:
+ case 0x5209:
+ rts5209_init_params(pcr);
+ break;
+
+ case 0x5229:
+ rts5229_init_params(pcr);
+ break;
+
+ case 0x5289:
+ rtl8411_init_params(pcr);
+ break;
+ }
+
+ dev_dbg(&(pcr->pci->dev), "PID: 0x%04x, IC version: 0x%02x\n",
+ PCI_PID(pcr), pcr->ic_version);
+
+ pcr->slots = kcalloc(pcr->num_slots, sizeof(struct rtsx_slot),
+ GFP_KERNEL);
+ if (!pcr->slots)
+ return -ENOMEM;
+
+ pcr->state = PDEV_STAT_IDLE;
+ err = rtsx_pci_init_hw(pcr);
+ if (err < 0) {
+ kfree(pcr->slots);
+ return err;
+ }
+
+ return 0;
+}
+
+static int __devinit rtsx_pci_probe(struct pci_dev *pcidev,
+ const struct pci_device_id *id)
+{
+ struct rtsx_pcr *pcr;
+ struct pcr_handle *handle;
+ u32 base, len;
+ int ret, i;
+
+ dev_dbg(&(pcidev->dev),
+ ": Realtek PCI-E Card Reader found at %s [%04x:%04x] (rev %x)\n",
+ pci_name(pcidev), (int)pcidev->vendor, (int)pcidev->device,
+ (int)pcidev->revision);
+
+ ret = pci_enable_device(pcidev);
+ if (ret)
+ return ret;
+
+ ret = pci_request_regions(pcidev, DRV_NAME_RTSX_PCI);
+ if (ret)
+ goto disable;
+
+ pcr = kzalloc(sizeof(*pcr), GFP_KERNEL);
+ if (!pcr) {
+ ret = -ENOMEM;
+ goto release_pci;
+ }
+
+ handle = kzalloc(sizeof(*handle), GFP_KERNEL);
+ if (!handle) {
+ ret = -ENOMEM;
+ goto free_pcr;
+ }
+ handle->pcr = pcr;
+
+ if (!idr_pre_get(&rtsx_pci_idr, GFP_KERNEL)) {
+ ret = -ENOMEM;
+ goto free_handle;
+ }
+
+ spin_lock(&rtsx_pci_lock);
+ ret = idr_get_new(&rtsx_pci_idr, pcr, &pcr->id);
+ spin_unlock(&rtsx_pci_lock);
+ if (ret)
+ goto free_handle;
+
+ pcr->pci = pcidev;
+ dev_set_drvdata(&pcidev->dev, handle);
+
+ len = pci_resource_len(pcidev, 0);
+ base = pci_resource_start(pcidev, 0);
+ pcr->remap_addr = ioremap_nocache(base, len);
+ if (!pcr->remap_addr) {
+ ret = -ENOMEM;
+ goto free_host;
+ }
+
+ pcr->rtsx_resv_buf = dma_alloc_coherent(&(pcidev->dev),
+ RTSX_RESV_BUF_LEN, &(pcr->rtsx_resv_buf_addr),
+ GFP_KERNEL);
+ if (pcr->rtsx_resv_buf == NULL) {
+ ret = -ENXIO;
+ goto unmap;
+ }
+ pcr->host_cmds_ptr = pcr->rtsx_resv_buf;
+ pcr->host_cmds_addr = pcr->rtsx_resv_buf_addr;
+ pcr->host_sg_tbl_ptr = pcr->rtsx_resv_buf + HOST_CMDS_BUF_LEN;
+ pcr->host_sg_tbl_addr = pcr->rtsx_resv_buf_addr + HOST_CMDS_BUF_LEN;
+
+ pcr->card_inserted = 0;
+ pcr->card_removed = 0;
+ INIT_DELAYED_WORK(&pcr->carddet_work, rtsx_pci_card_detect);
+ INIT_DELAYED_WORK(&pcr->idle_work, rtsx_pci_idle_work);
+
+ pcr->msi_en = msi_en;
+ if (pcr->msi_en) {
+ ret = pci_enable_msi(pcidev);
+ if (ret < 0)
+ pcr->msi_en = false;
+ }
+
+ ret = rtsx_pci_acquire_irq(pcr);
+ if (ret < 0)
+ goto free_dma;
+
+ pci_set_master(pcidev);
+ synchronize_irq(pcr->irq);
+
+ ret = rtsx_pci_init_chip(pcr);
+ if (ret < 0)
+ goto disable_irq;
+
+ for (i = 0; i < ARRAY_SIZE(rtsx_pcr_cells); i++) {
+ rtsx_pcr_cells[i].platform_data = handle;
+ rtsx_pcr_cells[i].pdata_size = sizeof(*handle);
+ }
+ ret = mfd_add_devices(&pcidev->dev, pcr->id, rtsx_pcr_cells,
+ ARRAY_SIZE(rtsx_pcr_cells), NULL, 0, NULL);
+ if (ret < 0)
+ goto disable_irq;
+
+ schedule_delayed_work(&pcr->idle_work, msecs_to_jiffies(200));
+
+ return 0;
+
+disable_irq:
+ free_irq(pcr->irq, (void *)pcr);
+free_dma:
+ dma_free_coherent(&(pcr->pci->dev), RTSX_RESV_BUF_LEN,
+ pcr->rtsx_resv_buf, pcr->rtsx_resv_buf_addr);
+unmap:
+ iounmap(pcr->remap_addr);
+free_host:
+ dev_set_drvdata(&pcidev->dev, NULL);
+free_handle:
+ kfree(handle);
+free_pcr:
+ kfree(pcr);
+release_pci:
+ pci_release_regions(pcidev);
+disable:
+ pci_disable_device(pcidev);
+
+ return ret;
+}
+
+static void __devexit rtsx_pci_remove(struct pci_dev *pcidev)
+{
+ struct pcr_handle *handle = pci_get_drvdata(pcidev);
+ struct rtsx_pcr *pcr = handle->pcr;
+
+ pcr->remove_pci = true;
+
+ cancel_delayed_work(&pcr->carddet_work);
+ cancel_delayed_work(&pcr->idle_work);
+
+ mfd_remove_devices(&pcidev->dev);
+
+ dma_free_coherent(&(pcr->pci->dev), RTSX_RESV_BUF_LEN,
+ pcr->rtsx_resv_buf, pcr->rtsx_resv_buf_addr);
+ free_irq(pcr->irq, (void *)pcr);
+ if (pcr->msi_en)
+ pci_disable_msi(pcr->pci);
+ iounmap(pcr->remap_addr);
+
+ dev_set_drvdata(&pcidev->dev, NULL);
+ pci_release_regions(pcidev);
+ pci_disable_device(pcidev);
+
+ spin_lock(&rtsx_pci_lock);
+ idr_remove(&rtsx_pci_idr, pcr->id);
+ spin_unlock(&rtsx_pci_lock);
+
+ kfree(pcr->slots);
+ kfree(pcr);
+ kfree(handle);
+
+ dev_dbg(&(pcidev->dev),
+ ": Realtek PCI-E Card Reader at %s [%04x:%04x] has been removed\n",
+ pci_name(pcidev), (int)pcidev->vendor, (int)pcidev->device);
+}
+
+#ifdef CONFIG_PM
+
+static int rtsx_pci_suspend(struct pci_dev *pcidev, pm_message_t state)
+{
+ struct pcr_handle *handle;
+ struct rtsx_pcr *pcr;
+ int ret = 0;
+
+ dev_dbg(&(pcidev->dev), "--> %s\n", __func__);
+
+ handle = pci_get_drvdata(pcidev);
+ pcr = handle->pcr;
+
+ cancel_delayed_work(&pcr->carddet_work);
+ cancel_delayed_work(&pcr->idle_work);
+
+ mutex_lock(&pcr->pcr_mutex);
+
+ if (pcr->ops->turn_off_led)
+ pcr->ops->turn_off_led(pcr);
+
+ rtsx_pci_writel(pcr, RTSX_BIER, 0);
+ pcr->bier = 0;
+
+ rtsx_pci_write_register(pcr, PETXCFG, 0x08, 0x08);
+ rtsx_pci_write_register(pcr, HOST_SLEEP_STATE, 0x03, 0x02);
+
+ pci_save_state(pcidev);
+ pci_enable_wake(pcidev, pci_choose_state(pcidev, state), 0);
+ pci_disable_device(pcidev);
+ pci_set_power_state(pcidev, pci_choose_state(pcidev, state));
+
+ mutex_unlock(&pcr->pcr_mutex);
+ return ret;
+}
+
+static int rtsx_pci_resume(struct pci_dev *pcidev)
+{
+ struct pcr_handle *handle;
+ struct rtsx_pcr *pcr;
+ int ret = 0;
+
+ dev_dbg(&(pcidev->dev), "--> %s\n", __func__);
+
+ handle = pci_get_drvdata(pcidev);
+ pcr = handle->pcr;
+
+ mutex_lock(&pcr->pcr_mutex);
+
+ pci_set_power_state(pcidev, PCI_D0);
+ pci_restore_state(pcidev);
+ ret = pci_enable_device(pcidev);
+ if (ret)
+ goto out;
+ pci_set_master(pcidev);
+
+ ret = rtsx_pci_write_register(pcr, HOST_SLEEP_STATE, 0x03, 0x00);
+ if (ret)
+ goto out;
+
+ ret = rtsx_pci_init_hw(pcr);
+ if (ret)
+ goto out;
+
+ schedule_delayed_work(&pcr->idle_work, msecs_to_jiffies(200));
+
+out:
+ mutex_unlock(&pcr->pcr_mutex);
+ return ret;
+}
+
+#else /* CONFIG_PM */
+
+#define rtsx_pci_suspend NULL
+#define rtsx_pci_resume NULL
+
+#endif /* CONFIG_PM */
+
+static struct pci_driver rtsx_pci_driver = {
+ .name = DRV_NAME_RTSX_PCI,
+ .id_table = rtsx_pci_ids,
+ .probe = rtsx_pci_probe,
+ .remove = __devexit_p(rtsx_pci_remove),
+ .suspend = rtsx_pci_suspend,
+ .resume = rtsx_pci_resume,
+};
+module_pci_driver(rtsx_pci_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Wei WANG <wei_wang@realsil.com.cn>");
+MODULE_DESCRIPTION("Realtek PCI-E Card Reader Driver");
diff --git a/drivers/mfd/rtsx_pcr.h b/drivers/mfd/rtsx_pcr.h
new file mode 100644
index 000000000000..12462c1df1a9
--- /dev/null
+++ b/drivers/mfd/rtsx_pcr.h
@@ -0,0 +1,32 @@
+/* Driver for Realtek PCI-Express card reader
+ *
+ * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ * Wei WANG <wei_wang@realsil.com.cn>
+ * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
+ */
+
+#ifndef __RTSX_PCR_H
+#define __RTSX_PCR_H
+
+#include <linux/mfd/rtsx_pci.h>
+
+void rts5209_init_params(struct rtsx_pcr *pcr);
+void rts5229_init_params(struct rtsx_pcr *pcr);
+void rtl8411_init_params(struct rtsx_pcr *pcr);
+
+#endif
diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c
index d927dd49acb3..9816c232e583 100644
--- a/drivers/mfd/sm501.c
+++ b/drivers/mfd/sm501.c
@@ -1014,7 +1014,7 @@ static struct gpio_chip gpio_chip_template = {
.get = sm501_gpio_get,
};
-static int __devinit sm501_gpio_register_chip(struct sm501_devdata *sm,
+static int sm501_gpio_register_chip(struct sm501_devdata *sm,
struct sm501_gpio *gpio,
struct sm501_gpio_chip *chip)
{
@@ -1042,7 +1042,7 @@ static int __devinit sm501_gpio_register_chip(struct sm501_devdata *sm,
return gpiochip_add(gchip);
}
-static int __devinit sm501_register_gpio(struct sm501_devdata *sm)
+static int sm501_register_gpio(struct sm501_devdata *sm)
{
struct sm501_gpio *gpio = &sm->gpio;
resource_size_t iobase = sm->io_res->start + SM501_GPIO;
@@ -1313,7 +1313,7 @@ static unsigned int sm501_mem_local[] = {
* Common init code for an SM501
*/
-static int __devinit sm501_init_dev(struct sm501_devdata *sm)
+static int sm501_init_dev(struct sm501_devdata *sm)
{
struct sm501_initdata *idata;
struct sm501_platdata *pdata;
@@ -1389,7 +1389,7 @@ static int __devinit sm501_init_dev(struct sm501_devdata *sm)
return 0;
}
-static int __devinit sm501_plat_probe(struct platform_device *dev)
+static int sm501_plat_probe(struct platform_device *dev)
{
struct sm501_devdata *sm;
int ret;
@@ -1578,7 +1578,7 @@ static struct sm501_platdata sm501_pci_platdata = {
.gpio_base = -1,
};
-static int __devinit sm501_pci_probe(struct pci_dev *dev,
+static int sm501_pci_probe(struct pci_dev *dev,
const struct pci_device_id *id)
{
struct sm501_devdata *sm;
@@ -1685,7 +1685,7 @@ static void sm501_dev_remove(struct sm501_devdata *sm)
sm501_gpio_remove(sm);
}
-static void __devexit sm501_pci_remove(struct pci_dev *dev)
+static void sm501_pci_remove(struct pci_dev *dev)
{
struct sm501_devdata *sm = pci_get_drvdata(dev);
@@ -1723,12 +1723,12 @@ static struct pci_driver sm501_pci_driver = {
.name = "sm501",
.id_table = sm501_pci_tbl,
.probe = sm501_pci_probe,
- .remove = __devexit_p(sm501_pci_remove),
+ .remove = sm501_pci_remove,
};
MODULE_ALIAS("platform:sm501");
-static struct of_device_id __devinitdata of_sm501_match_tbl[] = {
+static struct of_device_id of_sm501_match_tbl[] = {
{ .compatible = "smi,sm501", },
{ /* end */ }
};
diff --git a/drivers/mfd/sta2x11-mfd.c b/drivers/mfd/sta2x11-mfd.c
index d35da6820bea..d6284cacd27a 100644
--- a/drivers/mfd/sta2x11-mfd.c
+++ b/drivers/mfd/sta2x11-mfd.c
@@ -69,7 +69,7 @@ static struct sta2x11_mfd *sta2x11_mfd_find(struct pci_dev *pdev)
return NULL;
}
-static int __devinit sta2x11_mfd_add(struct pci_dev *pdev, gfp_t flags)
+static int sta2x11_mfd_add(struct pci_dev *pdev, gfp_t flags)
{
struct sta2x11_mfd *mfd = sta2x11_mfd_find(pdev);
struct sta2x11_instance *instance;
@@ -89,7 +89,7 @@ static int __devinit sta2x11_mfd_add(struct pci_dev *pdev, gfp_t flags)
return 0;
}
-static int __devexit mfd_remove(struct pci_dev *pdev)
+static int mfd_remove(struct pci_dev *pdev)
{
struct sta2x11_mfd *mfd = sta2x11_mfd_find(pdev);
@@ -305,7 +305,7 @@ enum bar1_cells {
.flags = IORESOURCE_MEM, \
}
-static const __devinitconst struct resource gpio_resources[] = {
+static const struct resource gpio_resources[] = {
{
.name = "sta2x11_gpio", /* 4 consecutive cells, 1 driver */
.start = 0,
@@ -313,31 +313,31 @@ static const __devinitconst struct resource gpio_resources[] = {
.flags = IORESOURCE_MEM,
}
};
-static const __devinitconst struct resource sctl_resources[] = {
+static const struct resource sctl_resources[] = {
CELL_4K("sta2x11-sctl", STA2X11_SCTL),
};
-static const __devinitconst struct resource scr_resources[] = {
+static const struct resource scr_resources[] = {
CELL_4K("sta2x11-scr", STA2X11_SCR),
};
-static const __devinitconst struct resource time_resources[] = {
+static const struct resource time_resources[] = {
CELL_4K("sta2x11-time", STA2X11_TIME),
};
-static const __devinitconst struct resource apbreg_resources[] = {
+static const struct resource apbreg_resources[] = {
CELL_4K("sta2x11-apbreg", STA2X11_APBREG),
};
#define DEV(_name, _r) \
{ .name = _name, .num_resources = ARRAY_SIZE(_r), .resources = _r, }
-static __devinitdata struct mfd_cell sta2x11_mfd_bar0[] = {
+static struct mfd_cell sta2x11_mfd_bar0[] = {
DEV("sta2x11-gpio", gpio_resources), /* offset 0: we add pdata later */
DEV("sta2x11-sctl", sctl_resources),
DEV("sta2x11-scr", scr_resources),
DEV("sta2x11-time", time_resources),
};
-static __devinitdata struct mfd_cell sta2x11_mfd_bar1[] = {
+static struct mfd_cell sta2x11_mfd_bar1[] = {
DEV("sta2x11-apbreg", apbreg_resources),
};
@@ -363,7 +363,7 @@ static int sta2x11_mfd_resume(struct pci_dev *pdev)
return 0;
}
-static int __devinit sta2x11_mfd_probe(struct pci_dev *pdev,
+static int sta2x11_mfd_probe(struct pci_dev *pdev,
const struct pci_device_id *pci_id)
{
int err, i;
diff --git a/drivers/mfd/stmpe-i2c.c b/drivers/mfd/stmpe-i2c.c
index 947a06a1845f..36df18778029 100644
--- a/drivers/mfd/stmpe-i2c.c
+++ b/drivers/mfd/stmpe-i2c.c
@@ -52,7 +52,7 @@ static struct stmpe_client_info i2c_ci = {
.write_block = i2c_block_write,
};
-static int __devinit
+static int
stmpe_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
{
i2c_ci.data = (void *)id;
@@ -63,7 +63,7 @@ stmpe_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
return stmpe_probe(&i2c_ci, id->driver_data);
}
-static int __devexit stmpe_i2c_remove(struct i2c_client *i2c)
+static int stmpe_i2c_remove(struct i2c_client *i2c)
{
struct stmpe *stmpe = dev_get_drvdata(&i2c->dev);
@@ -88,7 +88,7 @@ static struct i2c_driver stmpe_i2c_driver = {
.driver.pm = &stmpe_dev_pm_ops,
#endif
.probe = stmpe_i2c_probe,
- .remove = __devexit_p(stmpe_i2c_remove),
+ .remove = stmpe_i2c_remove,
.id_table = stmpe_i2c_id,
};
diff --git a/drivers/mfd/stmpe-spi.c b/drivers/mfd/stmpe-spi.c
index 9edfe864cc05..973659f8abd9 100644
--- a/drivers/mfd/stmpe-spi.c
+++ b/drivers/mfd/stmpe-spi.c
@@ -82,7 +82,7 @@ static struct stmpe_client_info spi_ci = {
.init = spi_init,
};
-static int __devinit
+static int
stmpe_spi_probe(struct spi_device *spi)
{
const struct spi_device_id *id = spi_get_device_id(spi);
@@ -101,7 +101,7 @@ stmpe_spi_probe(struct spi_device *spi)
return stmpe_probe(&spi_ci, id->driver_data);
}
-static int __devexit stmpe_spi_remove(struct spi_device *spi)
+static int stmpe_spi_remove(struct spi_device *spi)
{
struct stmpe *stmpe = dev_get_drvdata(&spi->dev);
@@ -128,7 +128,7 @@ static struct spi_driver stmpe_spi_driver = {
#endif
},
.probe = stmpe_spi_probe,
- .remove = __devexit_p(stmpe_spi_remove),
+ .remove = stmpe_spi_remove,
.id_table = stmpe_spi_id,
};
diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c
index c94f521f392c..79e88d1fd99a 100644
--- a/drivers/mfd/stmpe.c
+++ b/drivers/mfd/stmpe.c
@@ -294,12 +294,14 @@ static struct resource stmpe_gpio_resources[] = {
static struct mfd_cell stmpe_gpio_cell = {
.name = "stmpe-gpio",
+ .of_compatible = "st,stmpe-gpio",
.resources = stmpe_gpio_resources,
.num_resources = ARRAY_SIZE(stmpe_gpio_resources),
};
static struct mfd_cell stmpe_gpio_cell_noirq = {
.name = "stmpe-gpio",
+ .of_compatible = "st,stmpe-gpio",
/* gpio cell resources consist of an irq only so no resources here */
};
diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c
index 65fe609026cc..3f10591ea94e 100644
--- a/drivers/mfd/syscon.c
+++ b/drivers/mfd/syscon.c
@@ -97,7 +97,7 @@ static struct regmap_config syscon_regmap_config = {
.reg_stride = 4,
};
-static int __devinit syscon_probe(struct platform_device *pdev)
+static int syscon_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
@@ -138,7 +138,7 @@ static int __devinit syscon_probe(struct platform_device *pdev)
return 0;
}
-static int __devexit syscon_remove(struct platform_device *pdev)
+static int syscon_remove(struct platform_device *pdev)
{
struct syscon *syscon;
@@ -156,7 +156,7 @@ static struct platform_driver syscon_driver = {
.of_match_table = of_syscon_match,
},
.probe = syscon_probe,
- .remove = __devexit_p(syscon_remove),
+ .remove = syscon_remove,
};
static int __init syscon_init(void)
diff --git a/drivers/mfd/tc3589x.c b/drivers/mfd/tc3589x.c
index 8f4c853ca116..a06d66b929b1 100644
--- a/drivers/mfd/tc3589x.c
+++ b/drivers/mfd/tc3589x.c
@@ -282,7 +282,7 @@ static int tc3589x_chip_init(struct tc3589x *tc3589x)
return tc3589x_reg_write(tc3589x, TC3589x_RSTINTCLR, 0x1);
}
-static int __devinit tc3589x_device_init(struct tc3589x *tc3589x)
+static int tc3589x_device_init(struct tc3589x *tc3589x)
{
int ret = 0;
unsigned int blocks = tc3589x->pdata->block;
@@ -329,7 +329,7 @@ static int tc3589x_of_probe(struct device_node *np,
return 0;
}
-static int __devinit tc3589x_probe(struct i2c_client *i2c,
+static int tc3589x_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct tc3589x_platform_data *pdata = i2c->dev.platform_data;
@@ -402,7 +402,7 @@ out_free:
return ret;
}
-static int __devexit tc3589x_remove(struct i2c_client *client)
+static int tc3589x_remove(struct i2c_client *client)
{
struct tc3589x *tc3589x = i2c_get_clientdata(client);
@@ -458,7 +458,7 @@ static struct i2c_driver tc3589x_driver = {
.driver.owner = THIS_MODULE,
.driver.pm = &tc3589x_dev_pm_ops,
.probe = tc3589x_probe,
- .remove = __devexit_p(tc3589x_remove),
+ .remove = tc3589x_remove,
.id_table = tc3589x_id,
};
diff --git a/drivers/mfd/tc6387xb.c b/drivers/mfd/tc6387xb.c
index 413c891102f8..366f7b906278 100644
--- a/drivers/mfd/tc6387xb.c
+++ b/drivers/mfd/tc6387xb.c
@@ -138,7 +138,7 @@ static struct mfd_cell tc6387xb_cells[] = {
},
};
-static int __devinit tc6387xb_probe(struct platform_device *dev)
+static int tc6387xb_probe(struct platform_device *dev)
{
struct tc6387xb_platform_data *pdata = dev->dev.platform_data;
struct resource *iomem, *rscr;
@@ -208,7 +208,7 @@ err_no_irq:
return ret;
}
-static int __devexit tc6387xb_remove(struct platform_device *dev)
+static int tc6387xb_remove(struct platform_device *dev)
{
struct tc6387xb *tc6387xb = platform_get_drvdata(dev);
@@ -229,7 +229,7 @@ static struct platform_driver tc6387xb_platform_driver = {
.name = "tc6387xb",
},
.probe = tc6387xb_probe,
- .remove = __devexit_p(tc6387xb_remove),
+ .remove = tc6387xb_remove,
.suspend = tc6387xb_suspend,
.resume = tc6387xb_resume,
};
diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c
index dcab026fcbb2..15e1463e5e13 100644
--- a/drivers/mfd/tc6393xb.c
+++ b/drivers/mfd/tc6393xb.c
@@ -137,7 +137,7 @@ static int tc6393xb_nand_enable(struct platform_device *nand)
return 0;
}
-static struct resource __devinitdata tc6393xb_nand_resources[] = {
+static struct resource tc6393xb_nand_resources[] = {
{
.start = 0x1000,
.end = 0x1007,
@@ -196,7 +196,7 @@ static const struct resource tc6393xb_ohci_resources[] = {
},
};
-static struct resource __devinitdata tc6393xb_fb_resources[] = {
+static struct resource tc6393xb_fb_resources[] = {
{
.start = 0x5000,
.end = 0x51ff,
@@ -382,7 +382,7 @@ static struct tmio_mmc_data tc6393xb_mmc_data = {
.set_clk_div = tc6393xb_mmc_clk_div,
};
-static struct mfd_cell __devinitdata tc6393xb_cells[] = {
+static struct mfd_cell tc6393xb_cells[] = {
[TC6393XB_CELL_NAND] = {
.name = "tmio-nand",
.enable = tc6393xb_nand_enable,
@@ -602,7 +602,7 @@ static void tc6393xb_detach_irq(struct platform_device *dev)
/*--------------------------------------------------------------------------*/
-static int __devinit tc6393xb_probe(struct platform_device *dev)
+static int tc6393xb_probe(struct platform_device *dev)
{
struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
struct tc6393xb *tc6393xb;
@@ -731,7 +731,7 @@ err_kzalloc:
return ret;
}
-static int __devexit tc6393xb_remove(struct platform_device *dev)
+static int tc6393xb_remove(struct platform_device *dev)
{
struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
@@ -831,7 +831,7 @@ static int tc6393xb_resume(struct platform_device *dev)
static struct platform_driver tc6393xb_driver = {
.probe = tc6393xb_probe,
- .remove = __devexit_p(tc6393xb_remove),
+ .remove = tc6393xb_remove,
.suspend = tc6393xb_suspend,
.resume = tc6393xb_resume,
diff --git a/drivers/mfd/ti-ssp.c b/drivers/mfd/ti-ssp.c
index 7c3675a74f93..09a14cec351b 100644
--- a/drivers/mfd/ti-ssp.c
+++ b/drivers/mfd/ti-ssp.c
@@ -315,7 +315,7 @@ static irqreturn_t ti_ssp_interrupt(int irq, void *dev_data)
return IRQ_HANDLED;
}
-static int __devinit ti_ssp_probe(struct platform_device *pdev)
+static int ti_ssp_probe(struct platform_device *pdev)
{
static struct ti_ssp *ssp;
const struct ti_ssp_data *pdata = pdev->dev.platform_data;
@@ -433,7 +433,7 @@ error_res:
return error;
}
-static int __devexit ti_ssp_remove(struct platform_device *pdev)
+static int ti_ssp_remove(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct ti_ssp *ssp = dev_get_drvdata(dev);
@@ -451,7 +451,7 @@ static int __devexit ti_ssp_remove(struct platform_device *pdev)
static struct platform_driver ti_ssp_driver = {
.probe = ti_ssp_probe,
- .remove = __devexit_p(ti_ssp_remove),
+ .remove = ti_ssp_remove,
.driver = {
.name = "ti-ssp",
.owner = THIS_MODULE,
diff --git a/drivers/mfd/timberdale.c b/drivers/mfd/timberdale.c
index cccc626c83c8..59e0ee247e86 100644
--- a/drivers/mfd/timberdale.c
+++ b/drivers/mfd/timberdale.c
@@ -75,13 +75,13 @@ static struct i2c_board_info timberdale_i2c_board_info[] = {
},
};
-static __devinitdata struct xiic_i2c_platform_data
+static struct xiic_i2c_platform_data
timberdale_xiic_platform_data = {
.devices = timberdale_i2c_board_info,
.num_devices = ARRAY_SIZE(timberdale_i2c_board_info)
};
-static __devinitdata struct ocores_i2c_platform_data
+static struct ocores_i2c_platform_data
timberdale_ocores_platform_data = {
.reg_shift = 2,
.clock_khz = 62500,
@@ -89,7 +89,7 @@ timberdale_ocores_platform_data = {
.num_devices = ARRAY_SIZE(timberdale_i2c_board_info)
};
-static const __devinitconst struct resource timberdale_xiic_resources[] = {
+static const struct resource timberdale_xiic_resources[] = {
{
.start = XIICOFFSET,
.end = XIICEND,
@@ -102,7 +102,7 @@ static const __devinitconst struct resource timberdale_xiic_resources[] = {
},
};
-static const __devinitconst struct resource timberdale_ocores_resources[] = {
+static const struct resource timberdale_ocores_resources[] = {
{
.start = OCORESOFFSET,
.end = OCORESEND,
@@ -143,7 +143,7 @@ static struct spi_board_info timberdale_spi_8bit_board_info[] = {
},
};
-static __devinitdata struct xspi_platform_data timberdale_xspi_platform_data = {
+static struct xspi_platform_data timberdale_xspi_platform_data = {
.num_chipselect = 3,
.little_endian = true,
/* bits per word and devices will be filled in runtime depending
@@ -151,7 +151,7 @@ static __devinitdata struct xspi_platform_data timberdale_xspi_platform_data = {
*/
};
-static const __devinitconst struct resource timberdale_spi_resources[] = {
+static const struct resource timberdale_spi_resources[] = {
{
.start = SPIOFFSET,
.end = SPIEND,
@@ -164,13 +164,13 @@ static const __devinitconst struct resource timberdale_spi_resources[] = {
},
};
-static __devinitdata struct ks8842_platform_data
+static struct ks8842_platform_data
timberdale_ks8842_platform_data = {
.rx_dma_channel = DMA_ETH_RX,
.tx_dma_channel = DMA_ETH_TX
};
-static const __devinitconst struct resource timberdale_eth_resources[] = {
+static const struct resource timberdale_eth_resources[] = {
{
.start = ETHOFFSET,
.end = ETHEND,
@@ -183,14 +183,14 @@ static const __devinitconst struct resource timberdale_eth_resources[] = {
},
};
-static __devinitdata struct timbgpio_platform_data
+static struct timbgpio_platform_data
timberdale_gpio_platform_data = {
.gpio_base = 0,
.nr_pins = GPIO_NR_PINS,
.irq_base = 200,
};
-static const __devinitconst struct resource timberdale_gpio_resources[] = {
+static const struct resource timberdale_gpio_resources[] = {
{
.start = GPIOOFFSET,
.end = GPIOEND,
@@ -203,7 +203,7 @@ static const __devinitconst struct resource timberdale_gpio_resources[] = {
},
};
-static const __devinitconst struct resource timberdale_mlogicore_resources[] = {
+static const struct resource timberdale_mlogicore_resources[] = {
{
.start = MLCOREOFFSET,
.end = MLCOREEND,
@@ -221,7 +221,7 @@ static const __devinitconst struct resource timberdale_mlogicore_resources[] = {
},
};
-static const __devinitconst struct resource timberdale_uart_resources[] = {
+static const struct resource timberdale_uart_resources[] = {
{
.start = UARTOFFSET,
.end = UARTEND,
@@ -234,7 +234,7 @@ static const __devinitconst struct resource timberdale_uart_resources[] = {
},
};
-static const __devinitconst struct resource timberdale_uartlite_resources[] = {
+static const struct resource timberdale_uartlite_resources[] = {
{
.start = UARTLITEOFFSET,
.end = UARTLITEEND,
@@ -247,13 +247,13 @@ static const __devinitconst struct resource timberdale_uartlite_resources[] = {
},
};
-static __devinitdata struct i2c_board_info timberdale_adv7180_i2c_board_info = {
+static struct i2c_board_info timberdale_adv7180_i2c_board_info = {
/* Requires jumper JP9 to be off */
I2C_BOARD_INFO("adv7180", 0x42 >> 1),
.irq = IRQ_TIMBERDALE_ADV7180
};
-static __devinitdata struct timb_video_platform_data
+static struct timb_video_platform_data
timberdale_video_platform_data = {
.dma_channel = DMA_VIDEO_RX,
.i2c_adapter = 0,
@@ -262,7 +262,7 @@ static __devinitdata struct timb_video_platform_data
}
};
-static const __devinitconst struct resource
+static const struct resource
timberdale_radio_resources[] = {
{
.start = RDSOFFSET,
@@ -276,22 +276,22 @@ timberdale_radio_resources[] = {
},
};
-static __devinitdata struct i2c_board_info timberdale_tef6868_i2c_board_info = {
+static struct i2c_board_info timberdale_tef6868_i2c_board_info = {
I2C_BOARD_INFO("tef6862", 0x60)
};
-static __devinitdata struct i2c_board_info timberdale_saa7706_i2c_board_info = {
+static struct i2c_board_info timberdale_saa7706_i2c_board_info = {
I2C_BOARD_INFO("saa7706h", 0x1C)
};
-static __devinitdata struct timb_radio_platform_data
+static struct timb_radio_platform_data
timberdale_radio_platform_data = {
.i2c_adapter = 0,
.tuner = &timberdale_tef6868_i2c_board_info,
.dsp = &timberdale_saa7706_i2c_board_info
};
-static const __devinitconst struct resource timberdale_video_resources[] = {
+static const struct resource timberdale_video_resources[] = {
{
.start = LOGIWOFFSET,
.end = LOGIWEND,
@@ -303,7 +303,7 @@ static const __devinitconst struct resource timberdale_video_resources[] = {
*/
};
-static __devinitdata struct timb_dma_platform_data timb_dma_platform_data = {
+static struct timb_dma_platform_data timb_dma_platform_data = {
.nr_channels = 10,
.channels = {
{
@@ -362,7 +362,7 @@ static __devinitdata struct timb_dma_platform_data timb_dma_platform_data = {
}
};
-static const __devinitconst struct resource timberdale_dma_resources[] = {
+static const struct resource timberdale_dma_resources[] = {
{
.start = DMAOFFSET,
.end = DMAEND,
@@ -375,7 +375,7 @@ static const __devinitconst struct resource timberdale_dma_resources[] = {
},
};
-static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg0[] = {
+static struct mfd_cell timberdale_cells_bar0_cfg0[] = {
{
.name = "timb-dma",
.num_resources = ARRAY_SIZE(timberdale_dma_resources),
@@ -432,7 +432,7 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg0[] = {
},
};
-static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg1[] = {
+static struct mfd_cell timberdale_cells_bar0_cfg1[] = {
{
.name = "timb-dma",
.num_resources = ARRAY_SIZE(timberdale_dma_resources),
@@ -499,7 +499,7 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg1[] = {
},
};
-static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg2[] = {
+static struct mfd_cell timberdale_cells_bar0_cfg2[] = {
{
.name = "timb-dma",
.num_resources = ARRAY_SIZE(timberdale_dma_resources),
@@ -549,7 +549,7 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg2[] = {
},
};
-static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg3[] = {
+static struct mfd_cell timberdale_cells_bar0_cfg3[] = {
{
.name = "timb-dma",
.num_resources = ARRAY_SIZE(timberdale_dma_resources),
@@ -606,7 +606,7 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg3[] = {
},
};
-static const __devinitconst struct resource timberdale_sdhc_resources[] = {
+static const struct resource timberdale_sdhc_resources[] = {
/* located in bar 1 and bar 2 */
{
.start = SDHC0OFFSET,
@@ -620,7 +620,7 @@ static const __devinitconst struct resource timberdale_sdhc_resources[] = {
},
};
-static __devinitdata struct mfd_cell timberdale_cells_bar1[] = {
+static struct mfd_cell timberdale_cells_bar1[] = {
{
.name = "sdhci",
.num_resources = ARRAY_SIZE(timberdale_sdhc_resources),
@@ -628,7 +628,7 @@ static __devinitdata struct mfd_cell timberdale_cells_bar1[] = {
},
};
-static __devinitdata struct mfd_cell timberdale_cells_bar2[] = {
+static struct mfd_cell timberdale_cells_bar2[] = {
{
.name = "sdhci",
.num_resources = ARRAY_SIZE(timberdale_sdhc_resources),
@@ -650,7 +650,7 @@ static DEVICE_ATTR(fw_ver, S_IRUGO, show_fw_ver, NULL);
/*--------------------------------------------------------------------------*/
-static int __devinit timb_probe(struct pci_dev *dev,
+static int timb_probe(struct pci_dev *dev,
const struct pci_device_id *id)
{
struct timberdale_device *priv;
@@ -840,7 +840,7 @@ err_enable:
return -ENODEV;
}
-static void __devexit timb_remove(struct pci_dev *dev)
+static void timb_remove(struct pci_dev *dev)
{
struct timberdale_device *priv = pci_get_drvdata(dev);
@@ -867,7 +867,7 @@ static struct pci_driver timberdale_pci_driver = {
.name = DRIVER_NAME,
.id_table = timberdale_pci_tbl,
.probe = timb_probe,
- .remove = __devexit_p(timb_remove),
+ .remove = timb_remove,
};
static int __init timberdale_init(void)
diff --git a/drivers/mfd/tps6105x.c b/drivers/mfd/tps6105x.c
index 14051bdc714b..1d302f583adf 100644
--- a/drivers/mfd/tps6105x.c
+++ b/drivers/mfd/tps6105x.c
@@ -86,7 +86,7 @@ fail:
}
EXPORT_SYMBOL(tps6105x_mask_and_set);
-static int __devinit tps6105x_startup(struct tps6105x *tps6105x)
+static int tps6105x_startup(struct tps6105x *tps6105x)
{
int ret;
u8 regval;
@@ -133,7 +133,7 @@ static struct mfd_cell tps6105x_cells[] = {
},
};
-static int __devinit tps6105x_probe(struct i2c_client *client,
+static int tps6105x_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct tps6105x *tps6105x;
@@ -199,7 +199,7 @@ fail:
return ret;
}
-static int __devexit tps6105x_remove(struct i2c_client *client)
+static int tps6105x_remove(struct i2c_client *client)
{
struct tps6105x *tps6105x = i2c_get_clientdata(client);
@@ -226,7 +226,7 @@ static struct i2c_driver tps6105x_driver = {
.name = "tps6105x",
},
.probe = tps6105x_probe,
- .remove = __devexit_p(tps6105x_remove),
+ .remove = tps6105x_remove,
.id_table = tps6105x_id,
};
diff --git a/drivers/mfd/tps65090.c b/drivers/mfd/tps65090.c
index 074ae32b0d2a..382a857b0dde 100644
--- a/drivers/mfd/tps65090.c
+++ b/drivers/mfd/tps65090.c
@@ -188,7 +188,7 @@ static irqreturn_t tps65090_irq(int irq, void *data)
return acks ? IRQ_HANDLED : IRQ_NONE;
}
-static int __devinit tps65090_irq_init(struct tps65090 *tps65090, int irq,
+static int tps65090_irq_init(struct tps65090 *tps65090, int irq,
int irq_base)
{
int i, ret;
@@ -251,7 +251,7 @@ static const struct regmap_config tps65090_regmap_config = {
.volatile_reg = is_volatile_reg,
};
-static int __devinit tps65090_i2c_probe(struct i2c_client *client,
+static int tps65090_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct tps65090_platform_data *pdata = client->dev.platform_data;
@@ -308,7 +308,7 @@ err_exit:
return ret;
}
-static int __devexit tps65090_i2c_remove(struct i2c_client *client)
+static int tps65090_i2c_remove(struct i2c_client *client)
{
struct tps65090 *tps65090 = i2c_get_clientdata(client);
@@ -354,7 +354,7 @@ static struct i2c_driver tps65090_driver = {
.pm = &tps65090_pm_ops,
},
.probe = tps65090_i2c_probe,
- .remove = __devexit_p(tps65090_i2c_remove),
+ .remove = tps65090_i2c_remove,
.id_table = tps65090_id_table,
};
diff --git a/drivers/mfd/tps65217.c b/drivers/mfd/tps65217.c
index 3fb32e655254..e14e252e3473 100644
--- a/drivers/mfd/tps65217.c
+++ b/drivers/mfd/tps65217.c
@@ -153,7 +153,7 @@ static const struct of_device_id tps65217_of_match[] = {
{ /* sentinel */ },
};
-static int __devinit tps65217_probe(struct i2c_client *client,
+static int tps65217_probe(struct i2c_client *client,
const struct i2c_device_id *ids)
{
struct tps65217 *tps;
@@ -214,7 +214,7 @@ static int __devinit tps65217_probe(struct i2c_client *client,
return 0;
}
-static int __devexit tps65217_remove(struct i2c_client *client)
+static int tps65217_remove(struct i2c_client *client)
{
struct tps65217 *tps = i2c_get_clientdata(client);
@@ -237,7 +237,7 @@ static struct i2c_driver tps65217_driver = {
},
.id_table = tps65217_id_table,
.probe = tps65217_probe,
- .remove = __devexit_p(tps65217_remove),
+ .remove = tps65217_remove,
};
static int __init tps65217_init(void)
diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c
index 467464368773..87ba7ada3bbc 100644
--- a/drivers/mfd/tps6586x.c
+++ b/drivers/mfd/tps6586x.c
@@ -24,8 +24,6 @@
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/regmap.h>
-#include <linux/regulator/of_regulator.h>
-#include <linux/regulator/machine.h>
#include <linux/mfd/core.h>
#include <linux/mfd/tps6586x.h>
@@ -99,6 +97,9 @@ static struct mfd_cell tps6586x_cell[] = {
.name = "tps6586x-gpio",
},
{
+ .name = "tps6586x-pmic",
+ },
+ {
.name = "tps6586x-rtc",
},
{
@@ -267,7 +268,7 @@ static irqreturn_t tps6586x_irq(int irq, void *data)
return IRQ_HANDLED;
}
-static int __devinit tps6586x_irq_init(struct tps6586x *tps6586x, int irq,
+static int tps6586x_irq_init(struct tps6586x *tps6586x, int irq,
int irq_base)
{
int i, ret;
@@ -316,7 +317,7 @@ static int __devinit tps6586x_irq_init(struct tps6586x *tps6586x, int irq,
return ret;
}
-static int __devinit tps6586x_add_subdevs(struct tps6586x *tps6586x,
+static int tps6586x_add_subdevs(struct tps6586x *tps6586x,
struct tps6586x_platform_data *pdata)
{
struct tps6586x_subdev_info *subdev;
@@ -350,80 +351,19 @@ failed:
}
#ifdef CONFIG_OF
-static struct of_regulator_match tps6586x_matches[] = {
- { .name = "sys", .driver_data = (void *)TPS6586X_ID_SYS },
- { .name = "sm0", .driver_data = (void *)TPS6586X_ID_SM_0 },
- { .name = "sm1", .driver_data = (void *)TPS6586X_ID_SM_1 },
- { .name = "sm2", .driver_data = (void *)TPS6586X_ID_SM_2 },
- { .name = "ldo0", .driver_data = (void *)TPS6586X_ID_LDO_0 },
- { .name = "ldo1", .driver_data = (void *)TPS6586X_ID_LDO_1 },
- { .name = "ldo2", .driver_data = (void *)TPS6586X_ID_LDO_2 },
- { .name = "ldo3", .driver_data = (void *)TPS6586X_ID_LDO_3 },
- { .name = "ldo4", .driver_data = (void *)TPS6586X_ID_LDO_4 },
- { .name = "ldo5", .driver_data = (void *)TPS6586X_ID_LDO_5 },
- { .name = "ldo6", .driver_data = (void *)TPS6586X_ID_LDO_6 },
- { .name = "ldo7", .driver_data = (void *)TPS6586X_ID_LDO_7 },
- { .name = "ldo8", .driver_data = (void *)TPS6586X_ID_LDO_8 },
- { .name = "ldo9", .driver_data = (void *)TPS6586X_ID_LDO_9 },
- { .name = "ldo_rtc", .driver_data = (void *)TPS6586X_ID_LDO_RTC },
-};
-
static struct tps6586x_platform_data *tps6586x_parse_dt(struct i2c_client *client)
{
- const unsigned int num = ARRAY_SIZE(tps6586x_matches);
struct device_node *np = client->dev.of_node;
struct tps6586x_platform_data *pdata;
- struct tps6586x_subdev_info *devs;
- struct device_node *regs;
- const char *sys_rail_name = NULL;
- unsigned int count;
- unsigned int i, j;
- int err;
-
- regs = of_find_node_by_name(np, "regulators");
- if (!regs)
- return NULL;
-
- err = of_regulator_match(&client->dev, regs, tps6586x_matches, num);
- if (err < 0) {
- of_node_put(regs);
- return NULL;
- }
-
- of_node_put(regs);
- count = err;
-
- devs = devm_kzalloc(&client->dev, count * sizeof(*devs), GFP_KERNEL);
- if (!devs)
- return NULL;
-
- for (i = 0, j = 0; i < num && j < count; i++) {
- struct regulator_init_data *reg_idata;
-
- if (!tps6586x_matches[i].init_data)
- continue;
-
- reg_idata = tps6586x_matches[i].init_data;
- devs[j].name = "tps6586x-regulator";
- devs[j].platform_data = tps6586x_matches[i].init_data;
- devs[j].id = (int)tps6586x_matches[i].driver_data;
- if (devs[j].id == TPS6586X_ID_SYS)
- sys_rail_name = reg_idata->constraints.name;
-
- if ((devs[j].id == TPS6586X_ID_LDO_5) ||
- (devs[j].id == TPS6586X_ID_LDO_RTC))
- reg_idata->supply_regulator = sys_rail_name;
-
- devs[j].of_node = tps6586x_matches[i].of_node;
- j++;
- }
pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
- if (!pdata)
+ if (!pdata) {
+ dev_err(&client->dev, "Memory allocation failed\n");
return NULL;
+ }
- pdata->num_subdevs = count;
- pdata->subdevs = devs;
+ pdata->num_subdevs = 0;
+ pdata->subdevs = NULL;
pdata->gpio_base = -1;
pdata->irq_base = -1;
pdata->pm_off = of_property_read_bool(np, "ti,system-power-controller");
@@ -468,7 +408,7 @@ static void tps6586x_power_off(void)
tps6586x_set_bits(tps6586x_dev, TPS6586X_SUPPLYENE, SLEEP_MODE_BIT);
}
-static int __devinit tps6586x_i2c_probe(struct i2c_client *client,
+static int tps6586x_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct tps6586x_platform_data *pdata = client->dev.platform_data;
@@ -548,7 +488,7 @@ err_mfd_add:
return ret;
}
-static int __devexit tps6586x_i2c_remove(struct i2c_client *client)
+static int tps6586x_i2c_remove(struct i2c_client *client)
{
struct tps6586x *tps6586x = i2c_get_clientdata(client);
@@ -572,7 +512,7 @@ static struct i2c_driver tps6586x_driver = {
.of_match_table = of_match_ptr(tps6586x_of_match),
},
.probe = tps6586x_i2c_probe,
- .remove = __devexit_p(tps6586x_i2c_remove),
+ .remove = tps6586x_i2c_remove,
.id_table = tps6586x_id_table,
};
diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c
index 0d79ce2b5014..ce054654f5bb 100644
--- a/drivers/mfd/tps65910.c
+++ b/drivers/mfd/tps65910.c
@@ -78,7 +78,7 @@ static const struct regmap_config tps65910_regmap_config = {
.cache_type = REGCACHE_RBTREE,
};
-static int __devinit tps65910_ck32k_init(struct tps65910 *tps65910,
+static int tps65910_ck32k_init(struct tps65910 *tps65910,
struct tps65910_board *pmic_pdata)
{
int ret;
@@ -96,7 +96,7 @@ static int __devinit tps65910_ck32k_init(struct tps65910 *tps65910,
return 0;
}
-static int __devinit tps65910_sleepinit(struct tps65910 *tps65910,
+static int tps65910_sleepinit(struct tps65910 *tps65910,
struct tps65910_board *pmic_pdata)
{
struct device *dev = NULL;
@@ -237,7 +237,7 @@ static void tps65910_power_off(void)
DEVCTRL_DEV_ON_MASK);
}
-static __devinit int tps65910_i2c_probe(struct i2c_client *i2c,
+static int tps65910_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct tps65910 *tps65910;
@@ -302,7 +302,7 @@ static __devinit int tps65910_i2c_probe(struct i2c_client *i2c,
return ret;
}
-static __devexit int tps65910_i2c_remove(struct i2c_client *i2c)
+static int tps65910_i2c_remove(struct i2c_client *i2c)
{
struct tps65910 *tps65910 = i2c_get_clientdata(i2c);
@@ -327,7 +327,7 @@ static struct i2c_driver tps65910_i2c_driver = {
.of_match_table = of_match_ptr(tps65910_of_match),
},
.probe = tps65910_i2c_probe,
- .remove = __devexit_p(tps65910_i2c_remove),
+ .remove = tps65910_i2c_remove,
.id_table = tps65910_i2c_id,
};
diff --git a/drivers/mfd/tps65911-comparator.c b/drivers/mfd/tps65911-comparator.c
index 0b6e361432c4..c0816ebd9d7e 100644
--- a/drivers/mfd/tps65911-comparator.c
+++ b/drivers/mfd/tps65911-comparator.c
@@ -122,7 +122,7 @@ static ssize_t comp_threshold_show(struct device *dev,
static DEVICE_ATTR(comp1_threshold, S_IRUGO, comp_threshold_show, NULL);
static DEVICE_ATTR(comp2_threshold, S_IRUGO, comp_threshold_show, NULL);
-static __devinit int tps65911_comparator_probe(struct platform_device *pdev)
+static int tps65911_comparator_probe(struct platform_device *pdev)
{
struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent);
struct tps65910_board *pdata = dev_get_platdata(tps65910->dev);
@@ -152,7 +152,7 @@ static __devinit int tps65911_comparator_probe(struct platform_device *pdev)
return ret;
}
-static __devexit int tps65911_comparator_remove(struct platform_device *pdev)
+static int tps65911_comparator_remove(struct platform_device *pdev)
{
struct tps65910 *tps65910;
@@ -169,7 +169,7 @@ static struct platform_driver tps65911_comparator_driver = {
.owner = THIS_MODULE,
},
.probe = tps65911_comparator_probe,
- .remove = __devexit_p(tps65911_comparator_remove),
+ .remove = tps65911_comparator_remove,
};
static int __init tps65911_comparator_init(void)
diff --git a/drivers/mfd/tps65912-spi.c b/drivers/mfd/tps65912-spi.c
index 27d3302d56b8..b45f460d299f 100644
--- a/drivers/mfd/tps65912-spi.c
+++ b/drivers/mfd/tps65912-spi.c
@@ -81,7 +81,7 @@ static int tps65912_spi_read(struct tps65912 *tps65912, u8 addr,
return ret;
}
-static int __devinit tps65912_spi_probe(struct spi_device *spi)
+static int tps65912_spi_probe(struct spi_device *spi)
{
struct tps65912 *tps65912;
@@ -99,7 +99,7 @@ static int __devinit tps65912_spi_probe(struct spi_device *spi)
return tps65912_device_init(tps65912);
}
-static int __devexit tps65912_spi_remove(struct spi_device *spi)
+static int tps65912_spi_remove(struct spi_device *spi)
{
struct tps65912 *tps65912 = spi_get_drvdata(spi);
@@ -114,7 +114,7 @@ static struct spi_driver tps65912_spi_driver = {
.owner = THIS_MODULE,
},
.probe = tps65912_spi_probe,
- .remove = __devexit_p(tps65912_spi_remove),
+ .remove = tps65912_spi_remove,
};
static int __init tps65912_spi_init(void)
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index 4ae642320205..11b76c0109f5 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -671,7 +671,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base,
}
if (IS_ENABLED(CONFIG_PWM_TWL6030) && twl_class_is_6030()) {
- child = add_child(TWL6030_MODULE_ID1, "twl6030-pwm", NULL, 0,
+ child = add_child(SUB_CHIP_ID1, "twl6030-pwm", NULL, 0,
false, 0, 0);
if (IS_ERR(child))
return PTR_ERR(child);
@@ -1170,7 +1170,7 @@ static int twl_remove(struct i2c_client *client)
}
/* NOTE: This driver only handles a single twl4030/tps659x0 chip */
-static int __devinit
+static int
twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
struct twl4030_platform_data *pdata = client->dev.platform_data;
diff --git a/drivers/mfd/twl4030-audio.c b/drivers/mfd/twl4030-audio.c
index 5c11acf9e0fd..e16edca92670 100644
--- a/drivers/mfd/twl4030-audio.c
+++ b/drivers/mfd/twl4030-audio.c
@@ -184,7 +184,7 @@ static bool twl4030_audio_has_vibra(struct twl4030_audio_data *pdata,
return false;
}
-static int __devinit twl4030_audio_probe(struct platform_device *pdev)
+static int twl4030_audio_probe(struct platform_device *pdev)
{
struct twl4030_audio *audio;
struct twl4030_audio_data *pdata = pdev->dev.platform_data;
@@ -269,7 +269,7 @@ static int __devinit twl4030_audio_probe(struct platform_device *pdev)
return ret;
}
-static int __devexit twl4030_audio_remove(struct platform_device *pdev)
+static int twl4030_audio_remove(struct platform_device *pdev)
{
mfd_remove_devices(&pdev->dev);
platform_set_drvdata(pdev, NULL);
@@ -291,7 +291,7 @@ static struct platform_driver twl4030_audio_driver = {
.of_match_table = twl4030_audio_of_match,
},
.probe = twl4030_audio_probe,
- .remove = __devexit_p(twl4030_audio_remove),
+ .remove = twl4030_audio_remove,
};
module_platform_driver(twl4030_audio_driver);
diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c
index ad733d76207a..cdd1173ed4e9 100644
--- a/drivers/mfd/twl4030-irq.c
+++ b/drivers/mfd/twl4030-irq.c
@@ -672,7 +672,8 @@ int twl4030_sih_setup(struct device *dev, int module, int irq_base)
irq = sih_mod + twl4030_irq_base;
irq_set_handler_data(irq, agent);
agent->irq_name = kasprintf(GFP_KERNEL, "twl4030_%s", sih->name);
- status = request_threaded_irq(irq, NULL, handle_twl4030_sih, 0,
+ status = request_threaded_irq(irq, NULL, handle_twl4030_sih,
+ IRQF_EARLY_RESUME,
agent->irq_name ?: sih->name, NULL);
dev_info(dev, "%s (irq %d) chaining IRQs %d..%d\n", sih->name,
diff --git a/drivers/mfd/twl4030-madc.c b/drivers/mfd/twl4030-madc.c
index 456ecb5ac4fe..a39dcf3e2133 100644
--- a/drivers/mfd/twl4030-madc.c
+++ b/drivers/mfd/twl4030-madc.c
@@ -692,7 +692,7 @@ static int twl4030_madc_set_power(struct twl4030_madc_data *madc, int on)
/*
* Initialize MADC and request for threaded irq
*/
-static int __devinit twl4030_madc_probe(struct platform_device *pdev)
+static int twl4030_madc_probe(struct platform_device *pdev)
{
struct twl4030_madc_data *madc;
struct twl4030_madc_platform_data *pdata = pdev->dev.platform_data;
@@ -785,7 +785,7 @@ err_power:
return ret;
}
-static int __devexit twl4030_madc_remove(struct platform_device *pdev)
+static int twl4030_madc_remove(struct platform_device *pdev)
{
struct twl4030_madc_data *madc = platform_get_drvdata(pdev);
diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c
index 79ca33dfacca..a5332063183a 100644
--- a/drivers/mfd/twl4030-power.c
+++ b/drivers/mfd/twl4030-power.c
@@ -124,7 +124,7 @@ static u8 res_config_addrs[] = {
[RES_MAIN_REF] = 0x94,
};
-static int __devinit twl4030_write_script_byte(u8 address, u8 byte)
+static int twl4030_write_script_byte(u8 address, u8 byte)
{
int err;
@@ -138,7 +138,7 @@ out:
return err;
}
-static int __devinit twl4030_write_script_ins(u8 address, u16 pmb_message,
+static int twl4030_write_script_ins(u8 address, u16 pmb_message,
u8 delay, u8 next)
{
int err;
@@ -158,7 +158,7 @@ out:
return err;
}
-static int __devinit twl4030_write_script(u8 address, struct twl4030_ins *script,
+static int twl4030_write_script(u8 address, struct twl4030_ins *script,
int len)
{
int err;
@@ -183,7 +183,7 @@ static int __devinit twl4030_write_script(u8 address, struct twl4030_ins *script
return err;
}
-static int __devinit twl4030_config_wakeup3_sequence(u8 address)
+static int twl4030_config_wakeup3_sequence(u8 address)
{
int err;
u8 data;
@@ -208,7 +208,7 @@ out:
return err;
}
-static int __devinit twl4030_config_wakeup12_sequence(u8 address)
+static int twl4030_config_wakeup12_sequence(u8 address)
{
int err = 0;
u8 data;
@@ -262,7 +262,7 @@ out:
return err;
}
-static int __devinit twl4030_config_sleep_sequence(u8 address)
+static int twl4030_config_sleep_sequence(u8 address)
{
int err;
@@ -276,7 +276,7 @@ static int __devinit twl4030_config_sleep_sequence(u8 address)
return err;
}
-static int __devinit twl4030_config_warmreset_sequence(u8 address)
+static int twl4030_config_warmreset_sequence(u8 address)
{
int err;
u8 rd_data;
@@ -324,7 +324,7 @@ out:
return err;
}
-static int __devinit twl4030_configure_resource(struct twl4030_resconfig *rconfig)
+static int twl4030_configure_resource(struct twl4030_resconfig *rconfig)
{
int rconfig_addr;
int err;
@@ -416,7 +416,7 @@ static int __devinit twl4030_configure_resource(struct twl4030_resconfig *rconfi
return 0;
}
-static int __devinit load_twl4030_script(struct twl4030_script *tscript,
+static int load_twl4030_script(struct twl4030_script *tscript,
u8 address)
{
int err;
@@ -527,7 +527,7 @@ void twl4030_power_off(void)
pr_err("TWL4030 Unable to power off\n");
}
-void __devinit twl4030_power_init(struct twl4030_power_data *twl4030_scripts)
+void twl4030_power_init(struct twl4030_power_data *twl4030_scripts)
{
int err = 0;
int i;
diff --git a/drivers/mfd/vexpress-config.c b/drivers/mfd/vexpress-config.c
new file mode 100644
index 000000000000..fae15d880758
--- /dev/null
+++ b/drivers/mfd/vexpress-config.c
@@ -0,0 +1,277 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Copyright (C) 2012 ARM Limited
+ */
+
+#define pr_fmt(fmt) "vexpress-config: " fmt
+
+#include <linux/bitops.h>
+#include <linux/completion.h>
+#include <linux/export.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/vexpress.h>
+
+
+#define VEXPRESS_CONFIG_MAX_BRIDGES 2
+
+struct vexpress_config_bridge {
+ struct device_node *node;
+ struct vexpress_config_bridge_info *info;
+ struct list_head transactions;
+ spinlock_t transactions_lock;
+} vexpress_config_bridges[VEXPRESS_CONFIG_MAX_BRIDGES];
+
+static DECLARE_BITMAP(vexpress_config_bridges_map,
+ ARRAY_SIZE(vexpress_config_bridges));
+static DEFINE_MUTEX(vexpress_config_bridges_mutex);
+
+struct vexpress_config_bridge *vexpress_config_bridge_register(
+ struct device_node *node,
+ struct vexpress_config_bridge_info *info)
+{
+ struct vexpress_config_bridge *bridge;
+ int i;
+
+ pr_debug("Registering bridge '%s'\n", info->name);
+
+ mutex_lock(&vexpress_config_bridges_mutex);
+ i = find_first_zero_bit(vexpress_config_bridges_map,
+ ARRAY_SIZE(vexpress_config_bridges));
+ if (i >= ARRAY_SIZE(vexpress_config_bridges)) {
+ pr_err("Can't register more bridges!\n");
+ mutex_unlock(&vexpress_config_bridges_mutex);
+ return NULL;
+ }
+ __set_bit(i, vexpress_config_bridges_map);
+ bridge = &vexpress_config_bridges[i];
+
+ bridge->node = node;
+ bridge->info = info;
+ INIT_LIST_HEAD(&bridge->transactions);
+ spin_lock_init(&bridge->transactions_lock);
+
+ mutex_unlock(&vexpress_config_bridges_mutex);
+
+ return bridge;
+}
+
+void vexpress_config_bridge_unregister(struct vexpress_config_bridge *bridge)
+{
+ struct vexpress_config_bridge __bridge = *bridge;
+ int i;
+
+ mutex_lock(&vexpress_config_bridges_mutex);
+ for (i = 0; i < ARRAY_SIZE(vexpress_config_bridges); i++)
+ if (&vexpress_config_bridges[i] == bridge)
+ __clear_bit(i, vexpress_config_bridges_map);
+ mutex_unlock(&vexpress_config_bridges_mutex);
+
+ WARN_ON(!list_empty(&__bridge.transactions));
+ while (!list_empty(&__bridge.transactions))
+ cpu_relax();
+}
+
+
+struct vexpress_config_func {
+ struct vexpress_config_bridge *bridge;
+ void *func;
+};
+
+struct vexpress_config_func *__vexpress_config_func_get(struct device *dev,
+ struct device_node *node)
+{
+ struct device_node *bridge_node;
+ struct vexpress_config_func *func;
+ int i;
+
+ if (WARN_ON(dev && node && dev->of_node != node))
+ return NULL;
+ if (dev && !node)
+ node = dev->of_node;
+
+ func = kzalloc(sizeof(*func), GFP_KERNEL);
+ if (!func)
+ return NULL;
+
+ bridge_node = of_node_get(node);
+ while (bridge_node) {
+ const __be32 *prop = of_get_property(bridge_node,
+ "arm,vexpress,config-bridge", NULL);
+
+ if (prop) {
+ bridge_node = of_find_node_by_phandle(
+ be32_to_cpup(prop));
+ break;
+ }
+
+ bridge_node = of_get_next_parent(bridge_node);
+ }
+
+ mutex_lock(&vexpress_config_bridges_mutex);
+ for (i = 0; i < ARRAY_SIZE(vexpress_config_bridges); i++) {
+ struct vexpress_config_bridge *bridge =
+ &vexpress_config_bridges[i];
+
+ if (test_bit(i, vexpress_config_bridges_map) &&
+ bridge->node == bridge_node) {
+ func->bridge = bridge;
+ func->func = bridge->info->func_get(dev, node);
+ break;
+ }
+ }
+ mutex_unlock(&vexpress_config_bridges_mutex);
+
+ if (!func->func) {
+ of_node_put(node);
+ kfree(func);
+ return NULL;
+ }
+
+ return func;
+}
+
+void vexpress_config_func_put(struct vexpress_config_func *func)
+{
+ func->bridge->info->func_put(func->func);
+ of_node_put(func->bridge->node);
+ kfree(func);
+}
+
+
+struct vexpress_config_trans {
+ struct vexpress_config_func *func;
+ int offset;
+ bool write;
+ u32 *data;
+ int status;
+ struct completion completion;
+ struct list_head list;
+};
+
+static void vexpress_config_dump_trans(const char *what,
+ struct vexpress_config_trans *trans)
+{
+ pr_debug("%s %s trans %p func 0x%p offset %d data 0x%x status %d\n",
+ what, trans->write ? "write" : "read", trans,
+ trans->func->func, trans->offset,
+ trans->data ? *trans->data : 0, trans->status);
+}
+
+static int vexpress_config_schedule(struct vexpress_config_trans *trans)
+{
+ int status;
+ struct vexpress_config_bridge *bridge = trans->func->bridge;
+ unsigned long flags;
+
+ init_completion(&trans->completion);
+ trans->status = -EFAULT;
+
+ spin_lock_irqsave(&bridge->transactions_lock, flags);
+
+ vexpress_config_dump_trans("Executing", trans);
+
+ if (list_empty(&bridge->transactions))
+ status = bridge->info->func_exec(trans->func->func,
+ trans->offset, trans->write, trans->data);
+ else
+ status = VEXPRESS_CONFIG_STATUS_WAIT;
+
+ switch (status) {
+ case VEXPRESS_CONFIG_STATUS_DONE:
+ vexpress_config_dump_trans("Finished", trans);
+ trans->status = status;
+ break;
+ case VEXPRESS_CONFIG_STATUS_WAIT:
+ list_add_tail(&trans->list, &bridge->transactions);
+ break;
+ }
+
+ spin_unlock_irqrestore(&bridge->transactions_lock, flags);
+
+ return status;
+}
+
+void vexpress_config_complete(struct vexpress_config_bridge *bridge,
+ int status)
+{
+ struct vexpress_config_trans *trans;
+ unsigned long flags;
+
+ spin_lock_irqsave(&bridge->transactions_lock, flags);
+
+ trans = list_first_entry(&bridge->transactions,
+ struct vexpress_config_trans, list);
+ vexpress_config_dump_trans("Completed", trans);
+
+ trans->status = status;
+ list_del(&trans->list);
+
+ if (!list_empty(&bridge->transactions)) {
+ vexpress_config_dump_trans("Pending", trans);
+
+ bridge->info->func_exec(trans->func->func, trans->offset,
+ trans->write, trans->data);
+ }
+ spin_unlock_irqrestore(&bridge->transactions_lock, flags);
+
+ complete(&trans->completion);
+}
+
+int vexpress_config_wait(struct vexpress_config_trans *trans)
+{
+ wait_for_completion(&trans->completion);
+
+ return trans->status;
+}
+
+
+int vexpress_config_read(struct vexpress_config_func *func, int offset,
+ u32 *data)
+{
+ struct vexpress_config_trans trans = {
+ .func = func,
+ .offset = offset,
+ .write = false,
+ .data = data,
+ .status = 0,
+ };
+ int status = vexpress_config_schedule(&trans);
+
+ if (status == VEXPRESS_CONFIG_STATUS_WAIT)
+ status = vexpress_config_wait(&trans);
+
+ return status;
+}
+EXPORT_SYMBOL(vexpress_config_read);
+
+int vexpress_config_write(struct vexpress_config_func *func, int offset,
+ u32 data)
+{
+ struct vexpress_config_trans trans = {
+ .func = func,
+ .offset = offset,
+ .write = true,
+ .data = &data,
+ .status = 0,
+ };
+ int status = vexpress_config_schedule(&trans);
+
+ if (status == VEXPRESS_CONFIG_STATUS_WAIT)
+ status = vexpress_config_wait(&trans);
+
+ return status;
+}
+EXPORT_SYMBOL(vexpress_config_write);
diff --git a/drivers/mfd/vexpress-sysreg.c b/drivers/mfd/vexpress-sysreg.c
new file mode 100644
index 000000000000..733c06bd2d17
--- /dev/null
+++ b/drivers/mfd/vexpress-sysreg.c
@@ -0,0 +1,475 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Copyright (C) 2012 ARM Limited
+ */
+
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/leds.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/slab.h>
+#include <linux/stat.h>
+#include <linux/timer.h>
+#include <linux/vexpress.h>
+
+#define SYS_ID 0x000
+#define SYS_SW 0x004
+#define SYS_LED 0x008
+#define SYS_100HZ 0x024
+#define SYS_FLAGS 0x030
+#define SYS_FLAGSSET 0x030
+#define SYS_FLAGSCLR 0x034
+#define SYS_NVFLAGS 0x038
+#define SYS_NVFLAGSSET 0x038
+#define SYS_NVFLAGSCLR 0x03c
+#define SYS_MCI 0x048
+#define SYS_FLASH 0x04c
+#define SYS_CFGSW 0x058
+#define SYS_24MHZ 0x05c
+#define SYS_MISC 0x060
+#define SYS_DMA 0x064
+#define SYS_PROCID0 0x084
+#define SYS_PROCID1 0x088
+#define SYS_CFGDATA 0x0a0
+#define SYS_CFGCTRL 0x0a4
+#define SYS_CFGSTAT 0x0a8
+
+#define SYS_HBI_MASK 0xfff
+#define SYS_ID_HBI_SHIFT 16
+#define SYS_PROCIDx_HBI_SHIFT 0
+
+#define SYS_MCI_CARDIN (1 << 0)
+#define SYS_MCI_WPROT (1 << 1)
+
+#define SYS_FLASH_WPn (1 << 0)
+
+#define SYS_MISC_MASTERSITE (1 << 14)
+
+#define SYS_CFGCTRL_START (1 << 31)
+#define SYS_CFGCTRL_WRITE (1 << 30)
+#define SYS_CFGCTRL_DCC(n) (((n) & 0xf) << 26)
+#define SYS_CFGCTRL_FUNC(n) (((n) & 0x3f) << 20)
+#define SYS_CFGCTRL_SITE(n) (((n) & 0x3) << 16)
+#define SYS_CFGCTRL_POSITION(n) (((n) & 0xf) << 12)
+#define SYS_CFGCTRL_DEVICE(n) (((n) & 0xfff) << 0)
+
+#define SYS_CFGSTAT_ERR (1 << 1)
+#define SYS_CFGSTAT_COMPLETE (1 << 0)
+
+
+static void __iomem *vexpress_sysreg_base;
+static struct device *vexpress_sysreg_dev;
+static int vexpress_master_site;
+
+
+void vexpress_flags_set(u32 data)
+{
+ writel(~0, vexpress_sysreg_base + SYS_FLAGSCLR);
+ writel(data, vexpress_sysreg_base + SYS_FLAGSSET);
+}
+
+u32 vexpress_get_procid(int site)
+{
+ if (site == VEXPRESS_SITE_MASTER)
+ site = vexpress_master_site;
+
+ return readl(vexpress_sysreg_base + (site == VEXPRESS_SITE_DB1 ?
+ SYS_PROCID0 : SYS_PROCID1));
+}
+
+u32 vexpress_get_hbi(int site)
+{
+ u32 id;
+
+ switch (site) {
+ case VEXPRESS_SITE_MB:
+ id = readl(vexpress_sysreg_base + SYS_ID);
+ return (id >> SYS_ID_HBI_SHIFT) & SYS_HBI_MASK;
+ case VEXPRESS_SITE_MASTER:
+ case VEXPRESS_SITE_DB1:
+ case VEXPRESS_SITE_DB2:
+ id = vexpress_get_procid(site);
+ return (id >> SYS_PROCIDx_HBI_SHIFT) & SYS_HBI_MASK;
+ }
+
+ return ~0;
+}
+
+void __iomem *vexpress_get_24mhz_clock_base(void)
+{
+ return vexpress_sysreg_base + SYS_24MHZ;
+}
+
+
+static void vexpress_sysreg_find_prop(struct device_node *node,
+ const char *name, u32 *val)
+{
+ of_node_get(node);
+ while (node) {
+ if (of_property_read_u32(node, name, val) == 0) {
+ of_node_put(node);
+ return;
+ }
+ node = of_get_next_parent(node);
+ }
+}
+
+unsigned __vexpress_get_site(struct device *dev, struct device_node *node)
+{
+ u32 site = 0;
+
+ WARN_ON(dev && node && dev->of_node != node);
+ if (dev && !node)
+ node = dev->of_node;
+
+ if (node) {
+ vexpress_sysreg_find_prop(node, "arm,vexpress,site", &site);
+ } else if (dev && dev->bus == &platform_bus_type) {
+ struct platform_device *pdev = to_platform_device(dev);
+
+ if (pdev->num_resources == 1 &&
+ pdev->resource[0].flags == IORESOURCE_BUS)
+ site = pdev->resource[0].start;
+ } else if (dev && strncmp(dev_name(dev), "ct:", 3) == 0) {
+ site = VEXPRESS_SITE_MASTER;
+ }
+
+ if (site == VEXPRESS_SITE_MASTER)
+ site = vexpress_master_site;
+
+ return site;
+}
+
+
+struct vexpress_sysreg_config_func {
+ u32 template;
+ u32 device;
+};
+
+static struct vexpress_config_bridge *vexpress_sysreg_config_bridge;
+static struct timer_list vexpress_sysreg_config_timer;
+static u32 *vexpress_sysreg_config_data;
+static int vexpress_sysreg_config_tries;
+
+static void *vexpress_sysreg_config_func_get(struct device *dev,
+ struct device_node *node)
+{
+ struct vexpress_sysreg_config_func *config_func;
+ u32 site;
+ u32 position = 0;
+ u32 dcc = 0;
+ u32 func_device[2];
+ int err = -EFAULT;
+
+ if (node) {
+ of_node_get(node);
+ vexpress_sysreg_find_prop(node, "arm,vexpress,site", &site);
+ vexpress_sysreg_find_prop(node, "arm,vexpress,position",
+ &position);
+ vexpress_sysreg_find_prop(node, "arm,vexpress,dcc", &dcc);
+ err = of_property_read_u32_array(node,
+ "arm,vexpress-sysreg,func", func_device,
+ ARRAY_SIZE(func_device));
+ of_node_put(node);
+ } else if (dev && dev->bus == &platform_bus_type) {
+ struct platform_device *pdev = to_platform_device(dev);
+
+ if (pdev->num_resources == 1 &&
+ pdev->resource[0].flags == IORESOURCE_BUS) {
+ site = pdev->resource[0].start;
+ func_device[0] = pdev->resource[0].end;
+ func_device[1] = pdev->id;
+ err = 0;
+ }
+ }
+ if (err)
+ return NULL;
+
+ config_func = kzalloc(sizeof(*config_func), GFP_KERNEL);
+ if (!config_func)
+ return NULL;
+
+ config_func->template = SYS_CFGCTRL_DCC(dcc);
+ config_func->template |= SYS_CFGCTRL_FUNC(func_device[0]);
+ config_func->template |= SYS_CFGCTRL_SITE(site == VEXPRESS_SITE_MASTER ?
+ vexpress_master_site : site);
+ config_func->template |= SYS_CFGCTRL_POSITION(position);
+ config_func->device |= func_device[1];
+
+ dev_dbg(vexpress_sysreg_dev, "func 0x%p = 0x%x, %d\n", config_func,
+ config_func->template, config_func->device);
+
+ return config_func;
+}
+
+static void vexpress_sysreg_config_func_put(void *func)
+{
+ kfree(func);
+}
+
+static int vexpress_sysreg_config_func_exec(void *func, int offset,
+ bool write, u32 *data)
+{
+ int status;
+ struct vexpress_sysreg_config_func *config_func = func;
+ u32 command;
+
+ if (WARN_ON(!vexpress_sysreg_base))
+ return -ENOENT;
+
+ command = readl(vexpress_sysreg_base + SYS_CFGCTRL);
+ if (WARN_ON(command & SYS_CFGCTRL_START))
+ return -EBUSY;
+
+ command = SYS_CFGCTRL_START;
+ command |= write ? SYS_CFGCTRL_WRITE : 0;
+ command |= config_func->template;
+ command |= SYS_CFGCTRL_DEVICE(config_func->device + offset);
+
+ /* Use a canary for reads */
+ if (!write)
+ *data = 0xdeadbeef;
+
+ dev_dbg(vexpress_sysreg_dev, "command %x, data %x\n",
+ command, *data);
+ writel(*data, vexpress_sysreg_base + SYS_CFGDATA);
+ writel(0, vexpress_sysreg_base + SYS_CFGSTAT);
+ writel(command, vexpress_sysreg_base + SYS_CFGCTRL);
+ mb();
+
+ if (vexpress_sysreg_dev) {
+ /* Schedule completion check */
+ if (!write)
+ vexpress_sysreg_config_data = data;
+ vexpress_sysreg_config_tries = 100;
+ mod_timer(&vexpress_sysreg_config_timer,
+ jiffies + usecs_to_jiffies(100));
+ status = VEXPRESS_CONFIG_STATUS_WAIT;
+ } else {
+ /* Early execution, no timer available, have to spin */
+ u32 cfgstat;
+
+ do {
+ cpu_relax();
+ cfgstat = readl(vexpress_sysreg_base + SYS_CFGSTAT);
+ } while (!cfgstat);
+
+ if (!write && (cfgstat & SYS_CFGSTAT_COMPLETE))
+ *data = readl(vexpress_sysreg_base + SYS_CFGDATA);
+ status = VEXPRESS_CONFIG_STATUS_DONE;
+
+ if (cfgstat & SYS_CFGSTAT_ERR)
+ status = -EINVAL;
+ }
+
+ return status;
+}
+
+struct vexpress_config_bridge_info vexpress_sysreg_config_bridge_info = {
+ .name = "vexpress-sysreg",
+ .func_get = vexpress_sysreg_config_func_get,
+ .func_put = vexpress_sysreg_config_func_put,
+ .func_exec = vexpress_sysreg_config_func_exec,
+};
+
+static void vexpress_sysreg_config_complete(unsigned long data)
+{
+ int status = VEXPRESS_CONFIG_STATUS_DONE;
+ u32 cfgstat = readl(vexpress_sysreg_base + SYS_CFGSTAT);
+
+ if (cfgstat & SYS_CFGSTAT_ERR)
+ status = -EINVAL;
+ if (!vexpress_sysreg_config_tries--)
+ status = -ETIMEDOUT;
+
+ if (status < 0) {
+ dev_err(vexpress_sysreg_dev, "error %d\n", status);
+ } else if (!(cfgstat & SYS_CFGSTAT_COMPLETE)) {
+ mod_timer(&vexpress_sysreg_config_timer,
+ jiffies + usecs_to_jiffies(50));
+ return;
+ }
+
+ if (vexpress_sysreg_config_data) {
+ *vexpress_sysreg_config_data = readl(vexpress_sysreg_base +
+ SYS_CFGDATA);
+ dev_dbg(vexpress_sysreg_dev, "read data %x\n",
+ *vexpress_sysreg_config_data);
+ vexpress_sysreg_config_data = NULL;
+ }
+
+ vexpress_config_complete(vexpress_sysreg_config_bridge, status);
+}
+
+
+void __init vexpress_sysreg_early_init(void __iomem *base)
+{
+ struct device_node *node = of_find_compatible_node(NULL, NULL,
+ "arm,vexpress-sysreg");
+
+ if (node)
+ base = of_iomap(node, 0);
+
+ if (WARN_ON(!base))
+ return;
+
+ vexpress_sysreg_base = base;
+
+ if (readl(vexpress_sysreg_base + SYS_MISC) & SYS_MISC_MASTERSITE)
+ vexpress_master_site = VEXPRESS_SITE_DB2;
+ else
+ vexpress_master_site = VEXPRESS_SITE_DB1;
+
+ vexpress_sysreg_config_bridge = vexpress_config_bridge_register(
+ node, &vexpress_sysreg_config_bridge_info);
+ WARN_ON(!vexpress_sysreg_config_bridge);
+}
+
+void __init vexpress_sysreg_of_early_init(void)
+{
+ vexpress_sysreg_early_init(NULL);
+}
+
+
+static struct vexpress_sysreg_gpio {
+ unsigned long reg;
+ u32 value;
+} vexpress_sysreg_gpios[] = {
+ [VEXPRESS_GPIO_MMC_CARDIN] = {
+ .reg = SYS_MCI,
+ .value = SYS_MCI_CARDIN,
+ },
+ [VEXPRESS_GPIO_MMC_WPROT] = {
+ .reg = SYS_MCI,
+ .value = SYS_MCI_WPROT,
+ },
+ [VEXPRESS_GPIO_FLASH_WPn] = {
+ .reg = SYS_FLASH,
+ .value = SYS_FLASH_WPn,
+ },
+};
+
+static int vexpress_sysreg_gpio_direction_input(struct gpio_chip *chip,
+ unsigned offset)
+{
+ return 0;
+}
+
+static int vexpress_sysreg_gpio_direction_output(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ return 0;
+}
+
+static int vexpress_sysreg_gpio_get(struct gpio_chip *chip,
+ unsigned offset)
+{
+ struct vexpress_sysreg_gpio *gpio = &vexpress_sysreg_gpios[offset];
+ u32 reg_value = readl(vexpress_sysreg_base + gpio->reg);
+
+ return !!(reg_value & gpio->value);
+}
+
+static void vexpress_sysreg_gpio_set(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ struct vexpress_sysreg_gpio *gpio = &vexpress_sysreg_gpios[offset];
+ u32 reg_value = readl(vexpress_sysreg_base + gpio->reg);
+
+ if (value)
+ reg_value |= gpio->value;
+ else
+ reg_value &= ~gpio->value;
+
+ writel(reg_value, vexpress_sysreg_base + gpio->reg);
+}
+
+static struct gpio_chip vexpress_sysreg_gpio_chip = {
+ .label = "vexpress-sysreg",
+ .direction_input = vexpress_sysreg_gpio_direction_input,
+ .direction_output = vexpress_sysreg_gpio_direction_output,
+ .get = vexpress_sysreg_gpio_get,
+ .set = vexpress_sysreg_gpio_set,
+ .ngpio = ARRAY_SIZE(vexpress_sysreg_gpios),
+ .base = 0,
+};
+
+
+static ssize_t vexpress_sysreg_sys_id_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "0x%08x\n", readl(vexpress_sysreg_base + SYS_ID));
+}
+
+DEVICE_ATTR(sys_id, S_IRUGO, vexpress_sysreg_sys_id_show, NULL);
+
+static int __devinit vexpress_sysreg_probe(struct platform_device *pdev)
+{
+ int err;
+ struct resource *res = platform_get_resource(pdev,
+ IORESOURCE_MEM, 0);
+
+ if (!devm_request_mem_region(&pdev->dev, res->start,
+ resource_size(res), pdev->name)) {
+ dev_err(&pdev->dev, "Failed to request memory region!\n");
+ return -EBUSY;
+ }
+
+ if (!vexpress_sysreg_base)
+ vexpress_sysreg_base = devm_ioremap(&pdev->dev, res->start,
+ resource_size(res));
+
+ if (!vexpress_sysreg_base) {
+ dev_err(&pdev->dev, "Failed to obtain base address!\n");
+ return -EFAULT;
+ }
+
+ setup_timer(&vexpress_sysreg_config_timer,
+ vexpress_sysreg_config_complete, 0);
+
+ vexpress_sysreg_gpio_chip.dev = &pdev->dev;
+ err = gpiochip_add(&vexpress_sysreg_gpio_chip);
+ if (err) {
+ vexpress_config_bridge_unregister(
+ vexpress_sysreg_config_bridge);
+ dev_err(&pdev->dev, "Failed to register GPIO chip! (%d)\n",
+ err);
+ return err;
+ }
+
+ vexpress_sysreg_dev = &pdev->dev;
+
+ device_create_file(vexpress_sysreg_dev, &dev_attr_sys_id);
+
+ return 0;
+}
+
+static const struct of_device_id vexpress_sysreg_match[] = {
+ { .compatible = "arm,vexpress-sysreg", },
+ {},
+};
+
+static struct platform_driver vexpress_sysreg_driver = {
+ .driver = {
+ .name = "vexpress-sysreg",
+ .of_match_table = vexpress_sysreg_match,
+ },
+ .probe = vexpress_sysreg_probe,
+};
+
+static int __init vexpress_sysreg_init(void)
+{
+ return platform_driver_register(&vexpress_sysreg_driver);
+}
+core_initcall(vexpress_sysreg_init);
diff --git a/drivers/mfd/vx855.c b/drivers/mfd/vx855.c
index b9a636d44c7f..757ecc63338c 100644
--- a/drivers/mfd/vx855.c
+++ b/drivers/mfd/vx855.c
@@ -72,7 +72,7 @@ static struct mfd_cell vx855_cells[] = {
},
};
-static __devinit int vx855_probe(struct pci_dev *pdev,
+static int vx855_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
int ret;
@@ -112,7 +112,7 @@ out:
return ret;
}
-static void __devexit vx855_remove(struct pci_dev *pdev)
+static void vx855_remove(struct pci_dev *pdev)
{
mfd_remove_devices(&pdev->dev);
pci_disable_device(pdev);
@@ -128,7 +128,7 @@ static struct pci_driver vx855_pci_driver = {
.name = "vx855",
.id_table = vx855_pci_tbl,
.probe = vx855_probe,
- .remove = __devexit_p(vx855_remove),
+ .remove = vx855_remove,
};
module_pci_driver(vx855_pci_driver);
diff --git a/drivers/mfd/wl1273-core.c b/drivers/mfd/wl1273-core.c
index 86e0e4309fc2..edbe6c1b755a 100644
--- a/drivers/mfd/wl1273-core.c
+++ b/drivers/mfd/wl1273-core.c
@@ -182,7 +182,7 @@ static int wl1273_core_remove(struct i2c_client *client)
return 0;
}
-static int __devinit wl1273_core_probe(struct i2c_client *client,
+static int wl1273_core_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct wl1273_fm_platform_data *pdata = client->dev.platform_data;
@@ -262,7 +262,7 @@ static struct i2c_driver wl1273_core_driver = {
},
.probe = wl1273_core_probe,
.id_table = wl1273_driver_id_table,
- .remove = __devexit_p(wl1273_core_remove),
+ .remove = wl1273_core_remove,
};
static int __init wl1273_core_init(void)
diff --git a/drivers/mfd/wm5102-tables.c b/drivers/mfd/wm5102-tables.c
index 01b9255ed631..3141c4a173a7 100644
--- a/drivers/mfd/wm5102-tables.c
+++ b/drivers/mfd/wm5102-tables.c
@@ -43,6 +43,7 @@ static const struct reg_default wm5102_reva_patch[] = {
{ 0x479, 0x0A30 },
{ 0x47B, 0x0810 },
{ 0x47D, 0x0510 },
+ { 0x4D1, 0x017F },
{ 0x500, 0x000D },
{ 0x507, 0x1820 },
{ 0x508, 0x1820 },
@@ -52,524 +53,6 @@ static const struct reg_default wm5102_reva_patch[] = {
{ 0x580, 0x000D },
{ 0x587, 0x1820 },
{ 0x588, 0x1820 },
- { 0x101, 0x8140 },
- { 0x3000, 0x2225 },
- { 0x3001, 0x3a03 },
- { 0x3002, 0x0225 },
- { 0x3003, 0x0801 },
- { 0x3004, 0x6249 },
- { 0x3005, 0x0c04 },
- { 0x3006, 0x0225 },
- { 0x3007, 0x5901 },
- { 0x3008, 0xe249 },
- { 0x3009, 0x030d },
- { 0x300a, 0x0249 },
- { 0x300b, 0x2c01 },
- { 0x300c, 0xe249 },
- { 0x300d, 0x4342 },
- { 0x300e, 0xe249 },
- { 0x300f, 0x73c0 },
- { 0x3010, 0x4249 },
- { 0x3011, 0x0c00 },
- { 0x3012, 0x0225 },
- { 0x3013, 0x1f01 },
- { 0x3014, 0x0225 },
- { 0x3015, 0x1e01 },
- { 0x3016, 0x0225 },
- { 0x3017, 0xfa00 },
- { 0x3018, 0x0000 },
- { 0x3019, 0xf000 },
- { 0x301a, 0x0000 },
- { 0x301b, 0xf000 },
- { 0x301c, 0x0000 },
- { 0x301d, 0xf000 },
- { 0x301e, 0x0000 },
- { 0x301f, 0xf000 },
- { 0x3020, 0x0000 },
- { 0x3021, 0xf000 },
- { 0x3022, 0x0000 },
- { 0x3023, 0xf000 },
- { 0x3024, 0x0000 },
- { 0x3025, 0xf000 },
- { 0x3026, 0x0000 },
- { 0x3027, 0xf000 },
- { 0x3028, 0x0000 },
- { 0x3029, 0xf000 },
- { 0x302a, 0x0000 },
- { 0x302b, 0xf000 },
- { 0x302c, 0x0000 },
- { 0x302d, 0xf000 },
- { 0x302e, 0x0000 },
- { 0x302f, 0xf000 },
- { 0x3030, 0x0225 },
- { 0x3031, 0x1a01 },
- { 0x3032, 0x0225 },
- { 0x3033, 0x1e00 },
- { 0x3034, 0x0225 },
- { 0x3035, 0x1f00 },
- { 0x3036, 0x6225 },
- { 0x3037, 0xf800 },
- { 0x3038, 0x0000 },
- { 0x3039, 0xf000 },
- { 0x303a, 0x0000 },
- { 0x303b, 0xf000 },
- { 0x303c, 0x0000 },
- { 0x303d, 0xf000 },
- { 0x303e, 0x0000 },
- { 0x303f, 0xf000 },
- { 0x3040, 0x2226 },
- { 0x3041, 0x3a03 },
- { 0x3042, 0x0226 },
- { 0x3043, 0x0801 },
- { 0x3044, 0x6249 },
- { 0x3045, 0x0c06 },
- { 0x3046, 0x0226 },
- { 0x3047, 0x5901 },
- { 0x3048, 0xe249 },
- { 0x3049, 0x030d },
- { 0x304a, 0x0249 },
- { 0x304b, 0x2c01 },
- { 0x304c, 0xe249 },
- { 0x304d, 0x4342 },
- { 0x304e, 0xe249 },
- { 0x304f, 0x73c0 },
- { 0x3050, 0x4249 },
- { 0x3051, 0x0c00 },
- { 0x3052, 0x0226 },
- { 0x3053, 0x1f01 },
- { 0x3054, 0x0226 },
- { 0x3055, 0x1e01 },
- { 0x3056, 0x0226 },
- { 0x3057, 0xfa00 },
- { 0x3058, 0x0000 },
- { 0x3059, 0xf000 },
- { 0x305a, 0x0000 },
- { 0x305b, 0xf000 },
- { 0x305c, 0x0000 },
- { 0x305d, 0xf000 },
- { 0x305e, 0x0000 },
- { 0x305f, 0xf000 },
- { 0x3060, 0x0000 },
- { 0x3061, 0xf000 },
- { 0x3062, 0x0000 },
- { 0x3063, 0xf000 },
- { 0x3064, 0x0000 },
- { 0x3065, 0xf000 },
- { 0x3066, 0x0000 },
- { 0x3067, 0xf000 },
- { 0x3068, 0x0000 },
- { 0x3069, 0xf000 },
- { 0x306a, 0x0000 },
- { 0x306b, 0xf000 },
- { 0x306c, 0x0000 },
- { 0x306d, 0xf000 },
- { 0x306e, 0x0000 },
- { 0x306f, 0xf000 },
- { 0x3070, 0x0226 },
- { 0x3071, 0x1a01 },
- { 0x3072, 0x0226 },
- { 0x3073, 0x1e00 },
- { 0x3074, 0x0226 },
- { 0x3075, 0x1f00 },
- { 0x3076, 0x6226 },
- { 0x3077, 0xf800 },
- { 0x3078, 0x0000 },
- { 0x3079, 0xf000 },
- { 0x307a, 0x0000 },
- { 0x307b, 0xf000 },
- { 0x307c, 0x0000 },
- { 0x307d, 0xf000 },
- { 0x307e, 0x0000 },
- { 0x307f, 0xf000 },
- { 0x3080, 0x2227 },
- { 0x3081, 0x3a03 },
- { 0x3082, 0x0227 },
- { 0x3083, 0x0801 },
- { 0x3084, 0x6255 },
- { 0x3085, 0x0c04 },
- { 0x3086, 0x0227 },
- { 0x3087, 0x5901 },
- { 0x3088, 0xe255 },
- { 0x3089, 0x030d },
- { 0x308a, 0x0255 },
- { 0x308b, 0x2c01 },
- { 0x308c, 0xe255 },
- { 0x308d, 0x4342 },
- { 0x308e, 0xe255 },
- { 0x308f, 0x73c0 },
- { 0x3090, 0x4255 },
- { 0x3091, 0x0c00 },
- { 0x3092, 0x0227 },
- { 0x3093, 0x1f01 },
- { 0x3094, 0x0227 },
- { 0x3095, 0x1e01 },
- { 0x3096, 0x0227 },
- { 0x3097, 0xfa00 },
- { 0x3098, 0x0000 },
- { 0x3099, 0xf000 },
- { 0x309a, 0x0000 },
- { 0x309b, 0xf000 },
- { 0x309c, 0x0000 },
- { 0x309d, 0xf000 },
- { 0x309e, 0x0000 },
- { 0x309f, 0xf000 },
- { 0x30a0, 0x0000 },
- { 0x30a1, 0xf000 },
- { 0x30a2, 0x0000 },
- { 0x30a3, 0xf000 },
- { 0x30a4, 0x0000 },
- { 0x30a5, 0xf000 },
- { 0x30a6, 0x0000 },
- { 0x30a7, 0xf000 },
- { 0x30a8, 0x0000 },
- { 0x30a9, 0xf000 },
- { 0x30aa, 0x0000 },
- { 0x30ab, 0xf000 },
- { 0x30ac, 0x0000 },
- { 0x30ad, 0xf000 },
- { 0x30ae, 0x0000 },
- { 0x30af, 0xf000 },
- { 0x30b0, 0x0227 },
- { 0x30b1, 0x1a01 },
- { 0x30b2, 0x0227 },
- { 0x30b3, 0x1e00 },
- { 0x30b4, 0x0227 },
- { 0x30b5, 0x1f00 },
- { 0x30b6, 0x6227 },
- { 0x30b7, 0xf800 },
- { 0x30b8, 0x0000 },
- { 0x30b9, 0xf000 },
- { 0x30ba, 0x0000 },
- { 0x30bb, 0xf000 },
- { 0x30bc, 0x0000 },
- { 0x30bd, 0xf000 },
- { 0x30be, 0x0000 },
- { 0x30bf, 0xf000 },
- { 0x30c0, 0x2228 },
- { 0x30c1, 0x3a03 },
- { 0x30c2, 0x0228 },
- { 0x30c3, 0x0801 },
- { 0x30c4, 0x6255 },
- { 0x30c5, 0x0c06 },
- { 0x30c6, 0x0228 },
- { 0x30c7, 0x5901 },
- { 0x30c8, 0xe255 },
- { 0x30c9, 0x030d },
- { 0x30ca, 0x0255 },
- { 0x30cb, 0x2c01 },
- { 0x30cc, 0xe255 },
- { 0x30cd, 0x4342 },
- { 0x30ce, 0xe255 },
- { 0x30cf, 0x73c0 },
- { 0x30d0, 0x4255 },
- { 0x30d1, 0x0c00 },
- { 0x30d2, 0x0228 },
- { 0x30d3, 0x1f01 },
- { 0x30d4, 0x0228 },
- { 0x30d5, 0x1e01 },
- { 0x30d6, 0x0228 },
- { 0x30d7, 0xfa00 },
- { 0x30d8, 0x0000 },
- { 0x30d9, 0xf000 },
- { 0x30da, 0x0000 },
- { 0x30db, 0xf000 },
- { 0x30dc, 0x0000 },
- { 0x30dd, 0xf000 },
- { 0x30de, 0x0000 },
- { 0x30df, 0xf000 },
- { 0x30e0, 0x0000 },
- { 0x30e1, 0xf000 },
- { 0x30e2, 0x0000 },
- { 0x30e3, 0xf000 },
- { 0x30e4, 0x0000 },
- { 0x30e5, 0xf000 },
- { 0x30e6, 0x0000 },
- { 0x30e7, 0xf000 },
- { 0x30e8, 0x0000 },
- { 0x30e9, 0xf000 },
- { 0x30ea, 0x0000 },
- { 0x30eb, 0xf000 },
- { 0x30ec, 0x0000 },
- { 0x30ed, 0xf000 },
- { 0x30ee, 0x0000 },
- { 0x30ef, 0xf000 },
- { 0x30f0, 0x0228 },
- { 0x30f1, 0x1a01 },
- { 0x30f2, 0x0228 },
- { 0x30f3, 0x1e00 },
- { 0x30f4, 0x0228 },
- { 0x30f5, 0x1f00 },
- { 0x30f6, 0x6228 },
- { 0x30f7, 0xf800 },
- { 0x30f8, 0x0000 },
- { 0x30f9, 0xf000 },
- { 0x30fa, 0x0000 },
- { 0x30fb, 0xf000 },
- { 0x30fc, 0x0000 },
- { 0x30fd, 0xf000 },
- { 0x30fe, 0x0000 },
- { 0x30ff, 0xf000 },
- { 0x3100, 0x222b },
- { 0x3101, 0x3a03 },
- { 0x3102, 0x222b },
- { 0x3103, 0x5803 },
- { 0x3104, 0xe26f },
- { 0x3105, 0x030d },
- { 0x3106, 0x626f },
- { 0x3107, 0x2c01 },
- { 0x3108, 0xe26f },
- { 0x3109, 0x4342 },
- { 0x310a, 0xe26f },
- { 0x310b, 0x73c0 },
- { 0x310c, 0x026f },
- { 0x310d, 0x0c00 },
- { 0x310e, 0x022b },
- { 0x310f, 0x1f01 },
- { 0x3110, 0x022b },
- { 0x3111, 0x1e01 },
- { 0x3112, 0x022b },
- { 0x3113, 0xfa00 },
- { 0x3114, 0x0000 },
- { 0x3115, 0xf000 },
- { 0x3116, 0x0000 },
- { 0x3117, 0xf000 },
- { 0x3118, 0x0000 },
- { 0x3119, 0xf000 },
- { 0x311a, 0x0000 },
- { 0x311b, 0xf000 },
- { 0x311c, 0x0000 },
- { 0x311d, 0xf000 },
- { 0x311e, 0x0000 },
- { 0x311f, 0xf000 },
- { 0x3120, 0x022b },
- { 0x3121, 0x0a01 },
- { 0x3122, 0x022b },
- { 0x3123, 0x1e00 },
- { 0x3124, 0x022b },
- { 0x3125, 0x1f00 },
- { 0x3126, 0x622b },
- { 0x3127, 0xf800 },
- { 0x3128, 0x0000 },
- { 0x3129, 0xf000 },
- { 0x312a, 0x0000 },
- { 0x312b, 0xf000 },
- { 0x312c, 0x0000 },
- { 0x312d, 0xf000 },
- { 0x312e, 0x0000 },
- { 0x312f, 0xf000 },
- { 0x3130, 0x0000 },
- { 0x3131, 0xf000 },
- { 0x3132, 0x0000 },
- { 0x3133, 0xf000 },
- { 0x3134, 0x0000 },
- { 0x3135, 0xf000 },
- { 0x3136, 0x0000 },
- { 0x3137, 0xf000 },
- { 0x3138, 0x0000 },
- { 0x3139, 0xf000 },
- { 0x313a, 0x0000 },
- { 0x313b, 0xf000 },
- { 0x313c, 0x0000 },
- { 0x313d, 0xf000 },
- { 0x313e, 0x0000 },
- { 0x313f, 0xf000 },
- { 0x3140, 0x0000 },
- { 0x3141, 0xf000 },
- { 0x3142, 0x0000 },
- { 0x3143, 0xf000 },
- { 0x3144, 0x0000 },
- { 0x3145, 0xf000 },
- { 0x3146, 0x0000 },
- { 0x3147, 0xf000 },
- { 0x3148, 0x0000 },
- { 0x3149, 0xf000 },
- { 0x314a, 0x0000 },
- { 0x314b, 0xf000 },
- { 0x314c, 0x0000 },
- { 0x314d, 0xf000 },
- { 0x314e, 0x0000 },
- { 0x314f, 0xf000 },
- { 0x3150, 0x0000 },
- { 0x3151, 0xf000 },
- { 0x3152, 0x0000 },
- { 0x3153, 0xf000 },
- { 0x3154, 0x0000 },
- { 0x3155, 0xf000 },
- { 0x3156, 0x0000 },
- { 0x3157, 0xf000 },
- { 0x3158, 0x0000 },
- { 0x3159, 0xf000 },
- { 0x315a, 0x0000 },
- { 0x315b, 0xf000 },
- { 0x315c, 0x0000 },
- { 0x315d, 0xf000 },
- { 0x315e, 0x0000 },
- { 0x315f, 0xf000 },
- { 0x3160, 0x0000 },
- { 0x3161, 0xf000 },
- { 0x3162, 0x0000 },
- { 0x3163, 0xf000 },
- { 0x3164, 0x0000 },
- { 0x3165, 0xf000 },
- { 0x3166, 0x0000 },
- { 0x3167, 0xf000 },
- { 0x3168, 0x0000 },
- { 0x3169, 0xf000 },
- { 0x316a, 0x0000 },
- { 0x316b, 0xf000 },
- { 0x316c, 0x0000 },
- { 0x316d, 0xf000 },
- { 0x316e, 0x0000 },
- { 0x316f, 0xf000 },
- { 0x3170, 0x0000 },
- { 0x3171, 0xf000 },
- { 0x3172, 0x0000 },
- { 0x3173, 0xf000 },
- { 0x3174, 0x0000 },
- { 0x3175, 0xf000 },
- { 0x3176, 0x0000 },
- { 0x3177, 0xf000 },
- { 0x3178, 0x0000 },
- { 0x3179, 0xf000 },
- { 0x317a, 0x0000 },
- { 0x317b, 0xf000 },
- { 0x317c, 0x0000 },
- { 0x317d, 0xf000 },
- { 0x317e, 0x0000 },
- { 0x317f, 0xf000 },
- { 0x3180, 0x2001 },
- { 0x3181, 0xf101 },
- { 0x3182, 0x0000 },
- { 0x3183, 0xf000 },
- { 0x3184, 0x0000 },
- { 0x3185, 0xf000 },
- { 0x3186, 0x0000 },
- { 0x3187, 0xf000 },
- { 0x3188, 0x0000 },
- { 0x3189, 0xf000 },
- { 0x318a, 0x0000 },
- { 0x318b, 0xf000 },
- { 0x318c, 0x0000 },
- { 0x318d, 0xf000 },
- { 0x318e, 0x0000 },
- { 0x318f, 0xf000 },
- { 0x3190, 0x0000 },
- { 0x3191, 0xf000 },
- { 0x3192, 0x0000 },
- { 0x3193, 0xf000 },
- { 0x3194, 0x0000 },
- { 0x3195, 0xf000 },
- { 0x3196, 0x0000 },
- { 0x3197, 0xf000 },
- { 0x3198, 0x0000 },
- { 0x3199, 0xf000 },
- { 0x319a, 0x0000 },
- { 0x319b, 0xf000 },
- { 0x319c, 0x0000 },
- { 0x319d, 0xf000 },
- { 0x319e, 0x0000 },
- { 0x319f, 0xf000 },
- { 0x31a0, 0x0000 },
- { 0x31a1, 0xf000 },
- { 0x31a2, 0x0000 },
- { 0x31a3, 0xf000 },
- { 0x31a4, 0x0000 },
- { 0x31a5, 0xf000 },
- { 0x31a6, 0x0000 },
- { 0x31a7, 0xf000 },
- { 0x31a8, 0x0000 },
- { 0x31a9, 0xf000 },
- { 0x31aa, 0x0000 },
- { 0x31ab, 0xf000 },
- { 0x31ac, 0x0000 },
- { 0x31ad, 0xf000 },
- { 0x31ae, 0x0000 },
- { 0x31af, 0xf000 },
- { 0x31b0, 0x0000 },
- { 0x31b1, 0xf000 },
- { 0x31b2, 0x0000 },
- { 0x31b3, 0xf000 },
- { 0x31b4, 0x0000 },
- { 0x31b5, 0xf000 },
- { 0x31b6, 0x0000 },
- { 0x31b7, 0xf000 },
- { 0x31b8, 0x0000 },
- { 0x31b9, 0xf000 },
- { 0x31ba, 0x0000 },
- { 0x31bb, 0xf000 },
- { 0x31bc, 0x0000 },
- { 0x31bd, 0xf000 },
- { 0x31be, 0x0000 },
- { 0x31bf, 0xf000 },
- { 0x31c0, 0x0000 },
- { 0x31c1, 0xf000 },
- { 0x31c2, 0x0000 },
- { 0x31c3, 0xf000 },
- { 0x31c4, 0x0000 },
- { 0x31c5, 0xf000 },
- { 0x31c6, 0x0000 },
- { 0x31c7, 0xf000 },
- { 0x31c8, 0x0000 },
- { 0x31c9, 0xf000 },
- { 0x31ca, 0x0000 },
- { 0x31cb, 0xf000 },
- { 0x31cc, 0x0000 },
- { 0x31cd, 0xf000 },
- { 0x31ce, 0x0000 },
- { 0x31cf, 0xf000 },
- { 0x31d0, 0x0000 },
- { 0x31d1, 0xf000 },
- { 0x31d2, 0x0000 },
- { 0x31d3, 0xf000 },
- { 0x31d4, 0x0000 },
- { 0x31d5, 0xf000 },
- { 0x31d6, 0x0000 },
- { 0x31d7, 0xf000 },
- { 0x31d8, 0x0000 },
- { 0x31d9, 0xf000 },
- { 0x31da, 0x0000 },
- { 0x31db, 0xf000 },
- { 0x31dc, 0x0000 },
- { 0x31dd, 0xf000 },
- { 0x31de, 0x0000 },
- { 0x31df, 0xf000 },
- { 0x31e0, 0x0000 },
- { 0x31e1, 0xf000 },
- { 0x31e2, 0x0000 },
- { 0x31e3, 0xf000 },
- { 0x31e4, 0x0000 },
- { 0x31e5, 0xf000 },
- { 0x31e6, 0x0000 },
- { 0x31e7, 0xf000 },
- { 0x31e8, 0x0000 },
- { 0x31e9, 0xf000 },
- { 0x31ea, 0x0000 },
- { 0x31eb, 0xf000 },
- { 0x31ec, 0x0000 },
- { 0x31ed, 0xf000 },
- { 0x31ee, 0x0000 },
- { 0x31ef, 0xf000 },
- { 0x31f0, 0x0000 },
- { 0x31f1, 0xf000 },
- { 0x31f2, 0x0000 },
- { 0x31f3, 0xf000 },
- { 0x31f4, 0x0000 },
- { 0x31f5, 0xf000 },
- { 0x31f6, 0x0000 },
- { 0x31f7, 0xf000 },
- { 0x31f8, 0x0000 },
- { 0x31f9, 0xf000 },
- { 0x31fa, 0x0000 },
- { 0x31fb, 0xf000 },
- { 0x31fc, 0x0000 },
- { 0x31fd, 0xf000 },
- { 0x31fe, 0x0000 },
- { 0x31ff, 0xf000 },
- { 0x024d, 0xff50 },
- { 0x0252, 0xff50 },
- { 0x0259, 0x0112 },
- { 0x025e, 0x0112 },
- { 0x101, 0x0304 },
{ 0x80, 0x0000 },
};
@@ -775,6 +258,7 @@ static const struct reg_default wm5102_reg_default[] = {
{ 0x00000154, 0x0000 }, /* R340 - Rate Estimator 3 */
{ 0x00000155, 0x0000 }, /* R341 - Rate Estimator 4 */
{ 0x00000156, 0x0000 }, /* R342 - Rate Estimator 5 */
+ { 0x00000161, 0x0000 }, /* R353 - Dynamic Frequency Scaling 1 */
{ 0x00000171, 0x0000 }, /* R369 - FLL1 Control 1 */
{ 0x00000172, 0x0008 }, /* R370 - FLL1 Control 2 */
{ 0x00000173, 0x0018 }, /* R371 - FLL1 Control 3 */
@@ -1564,6 +1048,7 @@ static bool wm5102_readable_register(struct device *dev, unsigned int reg)
case ARIZONA_RATE_ESTIMATOR_3:
case ARIZONA_RATE_ESTIMATOR_4:
case ARIZONA_RATE_ESTIMATOR_5:
+ case ARIZONA_DYNAMIC_FREQUENCY_SCALING_1:
case ARIZONA_FLL1_CONTROL_1:
case ARIZONA_FLL1_CONTROL_2:
case ARIZONA_FLL1_CONTROL_3:
@@ -1596,6 +1081,7 @@ static bool wm5102_readable_register(struct device *dev, unsigned int reg)
case ARIZONA_FLL2_GPIO_CLOCK:
case ARIZONA_MIC_CHARGE_PUMP_1:
case ARIZONA_LDO1_CONTROL_1:
+ case ARIZONA_LDO1_CONTROL_2:
case ARIZONA_LDO2_CONTROL_1:
case ARIZONA_MIC_BIAS_CTRL_1:
case ARIZONA_MIC_BIAS_CTRL_2:
diff --git a/drivers/mfd/wm831x-spi.c b/drivers/mfd/wm831x-spi.c
index 4bceee98f0a4..4e70e157a909 100644
--- a/drivers/mfd/wm831x-spi.c
+++ b/drivers/mfd/wm831x-spi.c
@@ -21,7 +21,7 @@
#include <linux/mfd/wm831x/core.h>
-static int __devinit wm831x_spi_probe(struct spi_device *spi)
+static int wm831x_spi_probe(struct spi_device *spi)
{
const struct spi_device_id *id = spi_get_device_id(spi);
struct wm831x *wm831x;
@@ -51,7 +51,7 @@ static int __devinit wm831x_spi_probe(struct spi_device *spi)
return wm831x_device_init(wm831x, type, spi->irq);
}
-static int __devexit wm831x_spi_remove(struct spi_device *spi)
+static int wm831x_spi_remove(struct spi_device *spi)
{
struct wm831x *wm831x = dev_get_drvdata(&spi->dev);
@@ -99,7 +99,7 @@ static struct spi_driver wm831x_spi_driver = {
},
.id_table = wm831x_spi_ids,
.probe = wm831x_spi_probe,
- .remove = __devexit_p(wm831x_spi_remove),
+ .remove = wm831x_spi_remove,
.shutdown = wm831x_spi_shutdown,
};
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c
index 8fefc961ec06..bcb226ff9d2b 100644
--- a/drivers/mfd/wm8994-core.c
+++ b/drivers/mfd/wm8994-core.c
@@ -374,21 +374,21 @@ static int wm8994_ldo_in_use(struct wm8994_pdata *pdata, int ldo)
}
#endif
-static const __devinitconst struct reg_default wm8994_revc_patch[] = {
+static const struct reg_default wm8994_revc_patch[] = {
{ 0x102, 0x3 },
{ 0x56, 0x3 },
{ 0x817, 0x0 },
{ 0x102, 0x0 },
};
-static const __devinitconst struct reg_default wm8958_reva_patch[] = {
+static const struct reg_default wm8958_reva_patch[] = {
{ 0x102, 0x3 },
{ 0xcb, 0x81 },
{ 0x817, 0x0 },
{ 0x102, 0x0 },
};
-static const __devinitconst struct reg_default wm1811_reva_patch[] = {
+static const struct reg_default wm1811_reva_patch[] = {
{ 0x102, 0x3 },
{ 0x56, 0xc07 },
{ 0x5d, 0x7e },
@@ -399,15 +399,21 @@ static const __devinitconst struct reg_default wm1811_reva_patch[] = {
/*
* Instantiate the generic non-control parts of the device.
*/
-static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq)
+static int wm8994_device_init(struct wm8994 *wm8994, int irq)
{
- struct wm8994_pdata *pdata = wm8994->dev->platform_data;
+ struct wm8994_pdata *pdata;
struct regmap_config *regmap_config;
const struct reg_default *regmap_patch = NULL;
const char *devname;
int ret, i, patch_regs;
int pulls = 0;
+ if (dev_get_platdata(wm8994->dev)) {
+ pdata = dev_get_platdata(wm8994->dev);
+ wm8994->pdata = *pdata;
+ }
+ pdata = &wm8994->pdata;
+
dev_set_drvdata(wm8994->dev, wm8994);
/* Add the on-chip regulators first for bootstrapping */
@@ -604,24 +610,21 @@ static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq)
}
}
- if (pdata) {
- wm8994->irq_base = pdata->irq_base;
- wm8994->gpio_base = pdata->gpio_base;
-
- /* GPIO configuration is only applied if it's non-zero */
- for (i = 0; i < ARRAY_SIZE(pdata->gpio_defaults); i++) {
- if (pdata->gpio_defaults[i]) {
- wm8994_set_bits(wm8994, WM8994_GPIO_1 + i,
- 0xffff,
- pdata->gpio_defaults[i]);
- }
+ wm8994->irq_base = pdata->irq_base;
+ wm8994->gpio_base = pdata->gpio_base;
+
+ /* GPIO configuration is only applied if it's non-zero */
+ for (i = 0; i < ARRAY_SIZE(pdata->gpio_defaults); i++) {
+ if (pdata->gpio_defaults[i]) {
+ wm8994_set_bits(wm8994, WM8994_GPIO_1 + i,
+ 0xffff, pdata->gpio_defaults[i]);
}
+ }
- wm8994->ldo_ena_always_driven = pdata->ldo_ena_always_driven;
+ wm8994->ldo_ena_always_driven = pdata->ldo_ena_always_driven;
- if (pdata->spkmode_pu)
- pulls |= WM8994_SPKMODE_PU;
- }
+ if (pdata->spkmode_pu)
+ pulls |= WM8994_SPKMODE_PU;
/* Disable unneeded pulls */
wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2,
@@ -671,7 +674,7 @@ err:
return ret;
}
-static __devexit void wm8994_device_exit(struct wm8994 *wm8994)
+static void wm8994_device_exit(struct wm8994 *wm8994)
{
pm_runtime_disable(wm8994->dev);
mfd_remove_devices(wm8994->dev);
@@ -689,7 +692,7 @@ static const struct of_device_id wm8994_of_match[] = {
};
MODULE_DEVICE_TABLE(of, wm8994_of_match);
-static __devinit int wm8994_i2c_probe(struct i2c_client *i2c,
+static int wm8994_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct wm8994 *wm8994;
@@ -715,7 +718,7 @@ static __devinit int wm8994_i2c_probe(struct i2c_client *i2c,
return wm8994_device_init(wm8994, i2c->irq);
}
-static __devexit int wm8994_i2c_remove(struct i2c_client *i2c)
+static int wm8994_i2c_remove(struct i2c_client *i2c)
{
struct wm8994 *wm8994 = i2c_get_clientdata(i2c);
@@ -744,7 +747,7 @@ static struct i2c_driver wm8994_i2c_driver = {
.of_match_table = wm8994_of_match,
},
.probe = wm8994_i2c_probe,
- .remove = __devexit_p(wm8994_i2c_remove),
+ .remove = wm8994_i2c_remove,
.id_table = wm8994_i2c_id,
};