diff options
-rw-r--r-- | drivers/staging/cg2900/mfd/cg2900_chip.c | 72 | ||||
-rw-r--r-- | drivers/staging/cg2900/mfd/stlc2690_chip.c | 40 |
2 files changed, 81 insertions, 31 deletions
diff --git a/drivers/staging/cg2900/mfd/cg2900_chip.c b/drivers/staging/cg2900/mfd/cg2900_chip.c index 7b69a97285a..c438ef0bc9c 100644 --- a/drivers/staging/cg2900/mfd/cg2900_chip.c +++ b/drivers/staging/cg2900/mfd/cg2900_chip.c @@ -43,6 +43,10 @@ #include "cg2900_core.h" #include "cg2900_lib.h" +#ifndef MAX +#define MAX(x, y) (((x) > (y)) ? (x) : (y)) +#endif + #define MAIN_DEV (main_info->dev) #define BOOT_DEV (info->user_in_charge->dev) @@ -329,6 +333,9 @@ struct cg2900_skb_data { * @selftest_work: Delayed work for reading selftest results. * @nbr_of_polls: Number of times we should poll for selftest * results. + * @startup: True if system is starting up. + * @mfd_size: Number of MFD cells. + * @mfd_char_size: Number of MFD char device cells. */ struct cg2900_chip_info { struct device *dev; @@ -361,6 +368,9 @@ struct cg2900_chip_info { struct cg2900_user_data *fm_audio; struct cg2900_delayed_work_struct selftest_work; int nbr_of_polls; + bool startup; + int mfd_size; + int mfd_char_size; }; /** @@ -382,6 +392,9 @@ static struct main_info *main_info; */ static DECLARE_WAIT_QUEUE_HEAD(main_wait_queue); +static struct mfd_cell cg2900_devs[]; +static struct mfd_cell cg2900_char_devs[]; + static void chip_startup_finished(struct cg2900_chip_info *info, int err); static void chip_shutdown(struct cg2900_user_data *user); @@ -1137,6 +1150,38 @@ shut_down_chip: info->main_state = CG2900_IDLE; wake_up_all(&main_wait_queue); + /* If this is called during system startup, register the devices. */ + if (info->startup) { + int err; + + err = mfd_add_devices(dev->dev, main_info->cell_base_id, + cg2900_devs, info->mfd_size, NULL, 0); + if (err) { + dev_err(dev->dev, "Failed to add cg2900_devs (%d)\n", + err); + goto finished; + } + + err = mfd_add_devices(dev->dev, main_info->cell_base_id, + cg2900_char_devs, info->mfd_char_size, + NULL, 0); + if (err) { + dev_err(dev->dev, "Failed to add cg2900_char_devs (%d)" + "\n", err); + mfd_remove_devices(dev->dev); + goto finished; + } + + /* + * Increase base ID so next connected transport will not get the + * same device IDs. + */ + main_info->cell_base_id += MAX(info->mfd_size, + info->mfd_char_size); + info->startup = false; + } + +finished: kfree(my_work); } @@ -3184,7 +3229,6 @@ static bool check_chip_support(struct cg2900_chip_dev *dev) struct cg2900_platform_data *pf_data; struct cg2900_chip_info *info; int i; - int err; dev_dbg(dev->dev, "check_chip_support\n"); @@ -3272,22 +3316,15 @@ static bool check_chip_support(struct cg2900_chip_dev *dev) for (i = 0; i < ARRAY_SIZE(cg2900_char_devs); i++) set_plat_data(&cg2900_char_devs[i], dev); - err = mfd_add_devices(dev->dev, main_info->cell_base_id, cg2900_devs, - ARRAY_SIZE(cg2900_devs), NULL, 0); - if (err) { - dev_err(dev->dev, "Failed to add cg2900_devs (%d)\n", err); - goto err_handling_free_settings_name; - } + info->startup = true; + info->mfd_size = ARRAY_SIZE(cg2900_devs); + info->mfd_char_size = ARRAY_SIZE(cg2900_char_devs); - err = mfd_add_devices(dev->dev, main_info->cell_base_id, - cg2900_char_devs, ARRAY_SIZE(cg2900_char_devs), - NULL, 0); - if (err) { - dev_err(dev->dev, "Failed to add cg2900_char_devs (%d)\n", err); - goto err_handling_remove_devs; - } + /* + * The devices will be registered when chip has been powered down, i.e. + * when the system startup is ready. + */ - main_info->cell_base_id += 30; mutex_unlock(&main_info->man_mutex); dev_info(dev->dev, "Chip supported by the CG2900 chip driver\n"); @@ -3297,11 +3334,6 @@ static bool check_chip_support(struct cg2900_chip_dev *dev) return true; -err_handling_remove_devs: - mfd_remove_devices(dev->dev); -err_handling_free_settings_name: - kfree(info->settings_file_name); - mutex_unlock(&main_info->man_mutex); err_handling_free_patch_name: kfree(info->patch_file_name); err_handling_destroy_wq: diff --git a/drivers/staging/cg2900/mfd/stlc2690_chip.c b/drivers/staging/cg2900/mfd/stlc2690_chip.c index a1167d9ece1..84de0d7a976 100644 --- a/drivers/staging/cg2900/mfd/stlc2690_chip.c +++ b/drivers/staging/cg2900/mfd/stlc2690_chip.c @@ -42,6 +42,10 @@ #include "cg2900_lib.h" #include "stlc2690_chip.h" +#ifndef MAX +#define MAX(x, y) (((x) > (y)) ? (x) : (y)) +#endif + #define MAIN_DEV (main_info->dev) #define BOOT_DEV (info->user_in_charge->dev) @@ -211,6 +215,9 @@ struct stlc2690_skb_data { * channel open and close. * @last_user: Last user of this chip. * @logger: Logger user of this chip. + * @startup: True if system is starting up. + * @mfd_size: Number of MFD cells. + * @mfd_char_size: Number of MFD char device cells. */ struct stlc2690_chip_info { char *patch_file_name; @@ -227,6 +234,9 @@ struct stlc2690_chip_info { struct cg2900_user_data *user_in_charge; struct cg2900_user_data *last_user; struct cg2900_user_data *logger; + bool startup; + int mfd_size; + int mfd_char_size; }; /** @@ -248,6 +258,9 @@ static struct main_info *main_info; */ static DECLARE_WAIT_QUEUE_HEAD(main_wait_queue); +static struct mfd_cell stlc2690_devs[]; +static struct mfd_cell stlc2690_char_devs[]; + static void chip_startup_finished(struct stlc2690_chip_info *info, int err); /** @@ -1499,6 +1512,16 @@ static bool check_chip_support(struct cg2900_chip_dev *dev) set_plat_data(&stlc2690_devs[i], dev); for (i = 0; i < ARRAY_SIZE(stlc2690_char_devs); i++) set_plat_data(&stlc2690_char_devs[i], dev); + mutex_unlock(&main_info->man_mutex); + + dev_info(dev->dev, "Chip supported by the STLC2690 chip driver\n"); + + /* Close the transport, which will power off the chip */ + if (dev->t_cb.close) + dev->t_cb.close(dev); + + dev_dbg(dev->dev, "New main_state: STLC2690_IDLE\n"); + info->main_state = STLC2690_IDLE; err = mfd_add_devices(dev->dev, main_info->cell_base_id, stlc2690_devs, ARRAY_SIZE(stlc2690_devs), NULL, 0); @@ -1516,17 +1539,12 @@ static bool check_chip_support(struct cg2900_chip_dev *dev) goto err_handling_remove_devs; } - main_info->cell_base_id += 30; - mutex_unlock(&main_info->man_mutex); - - dev_info(dev->dev, "Chip supported by the STLC2690 chip driver\n"); - - /* Close the transport, which will power off the chip */ - if (dev->t_cb.close) - dev->t_cb.close(dev); - - dev_dbg(dev->dev, "New main_state: STLC2690_IDLE\n"); - info->main_state = STLC2690_IDLE; + /* + * Increase base ID so next connected transport will not get the + * same device IDs. + */ + main_info->cell_base_id += MAX(ARRAY_SIZE(stlc2690_devs), + ARRAY_SIZE(stlc2690_char_devs)); return true; |