summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPar-Gunnar Hjalmdahl <par-gunnar.p.hjalmdahl@stericsson.com>2011-09-01 14:56:17 +0200
committerPhilippe Langlais <philippe.langlais@stericsson.com>2012-05-22 11:05:52 +0200
commit30e77baf660da681f59e8dc42c9e6363dde90226 (patch)
treed681d0c14d13c4768a1cae8ea0fa83254b23b300
parentcbf0b0d42090a579c2c6ed43608abcdff6b46254 (diff)
cg2900: Delay creation of MFD devices
This patch changes behavior when a chip transport is connected, i.e. normally during startup of system. It became obvious that this change was needed when commit ab81cbf99c881ca2b9a83682a8722fc84b2483d2 was introduced. We now wait until startup is finished, i.e. after shutting down the chip, before we register the MFD devices. ST-Ericsson ID: 352334 ST-Ericcson FOSS-OUT-ID: Trivial ST-Ericsson Linux next: 274079 Signed-off-by: Par-Gunnar Hjalmdahl <par-gunnar.p.hjalmdahl@stericsson.com> Change-Id: I48983ac4363600daf99a8edd2d3bfb9093ef94d4 Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/29938 Reviewed-by: Par-Gunnar HJALMDAHL <par-gunnar.p.hjalmdahl@stericsson.com> Tested-by: Par-Gunnar HJALMDAHL <par-gunnar.p.hjalmdahl@stericsson.com>
-rw-r--r--drivers/staging/cg2900/mfd/cg2900_chip.c72
-rw-r--r--drivers/staging/cg2900/mfd/stlc2690_chip.c40
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;