diff options
Diffstat (limited to 'drivers/mfd')
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, }; |