Patchwork [V3,11/13] SD card: introduce "spi" property for SD card objects

login
register
mail settings
Submitter Mitsyanko Igor
Date April 27, 2012, 3:50 p.m.
Message ID <1335541859-28829-12-git-send-email-i.mitsyanko@samsung.com>
Download mbox | patch
Permalink /patch/155547/
State New
Headers show

Comments

Mitsyanko Igor - April 27, 2012, 3:50 p.m.
And drop passing is_spi argument to SDCardClass::init function.
"spi" property could be set while SD card is in IDLE state. It defaults to "false".

Signed-off-by: Igor Mitsyanko <i.mitsyanko@samsung.com>
---
 hw/sd.c |   33 +++++++++++++++++++++++++++++++--
 hw/sd.h |    8 ++++++--
 2 files changed, 37 insertions(+), 4 deletions(-)
Paul Brook - April 30, 2012, 4:11 p.m.
> And drop passing is_spi argument to SDCardClass::init function.
> "spi" property could be set while SD card is in IDLE state. It defaults to
> "false".

Why?  This isn't something that should be under user or board control.  The SD 
card object is an implementation detail.  It's something that's part of the 
host controller. i.e. ether an SD host controller or an SPI bus device.

Do you have an example of why you would need to defer this decision?

If you want to separate instantiation of the SD card from the controller (e.g. 
to implement sdio devices) then you need a SD bus, plus an sd card device.  
Something like we do for spi connected cards.

Paul

Patch

diff --git a/hw/sd.c b/hw/sd.c
index fe2c138..744c338 100644
--- a/hw/sd.c
+++ b/hw/sd.c
@@ -491,10 +491,9 @@  static const VMStateDescription sd_vmstate = {
    whether card should be in SSI or MMC/SD mode.  It is also up to the
    board to ensure that ssi transfers only occur when the chip select
    is asserted.  */
-static void sd_init_card(SDState *sd, BlockDriverState *bs, bool is_spi)
+static void sd_init_card(SDState *sd, BlockDriverState *bs)
 {
     sd->buf = qemu_blockalign(bs, 512);
-    sd->spi = is_spi;
     sd->enable = true;
     sd_reset(sd, bs);
     if (sd->bdrv) {
@@ -1766,10 +1765,40 @@  static void sd_class_init(ObjectClass *klass, void *data)
     k->enable = sd_enable_card;
 }
 
+static void sd_is_spi(Object *obj, Visitor *v, void *opaque,
+                         const char *name, Error **errp)
+{
+    SDState *sd = SD_CARD(obj);
+
+    visit_type_bool(v, &sd->spi, name, errp);
+}
+
+static void sd_set_spimode(Object *obj, Visitor *v, void *opaque,
+                         const char *name, Error **errp)
+{
+    SDState *sd = SD_CARD(obj);
+
+    if (sd->state != sd_idle_state) {
+        error_set(errp, QERR_DEVICE_IN_USE, bdrv_get_device_name(sd->bdrv));
+    } else {
+        visit_type_bool(v, &sd->spi, name, errp);
+    }
+}
+
+static void sd_initfn(Object *obj)
+{
+    SDState *sd = SD_CARD(obj);
+
+    sd->spi = false;
+    object_property_add(obj, "spi", "boolean", sd_is_spi, sd_set_spimode,
+            NULL, NULL, NULL);
+}
+
 static const TypeInfo sd_type_info = {
     .name = TYPE_SD_CARD,
     .parent = TYPE_OBJECT,
     .instance_size = sizeof(SDState),
+    .instance_init = sd_initfn,
     .class_init = sd_class_init,
     .class_size = sizeof(SDClass)
 };
diff --git a/hw/sd.h b/hw/sd.h
index f84e863..c78eaa1 100644
--- a/hw/sd.h
+++ b/hw/sd.h
@@ -31,6 +31,7 @@ 
 
 #include "qemu-common.h"
 #include "qemu/object.h"
+#include "qapi/qapi-visit-core.h"
 
 #define OUT_OF_RANGE		(1 << 31)
 #define ADDRESS_ERROR		(1 << 30)
@@ -73,7 +74,7 @@  typedef struct SDState SDState;
 typedef struct SDClass {
     ObjectClass parent_class;
 
-    void (*init)(SDState *sd, BlockDriverState *bs, bool is_spi);
+    void (*init)(SDState *sd, BlockDriverState *bdrv);
     int (*do_command)(SDState *sd, SDRequest *req, uint8_t *response);
     void (*write_data)(SDState *sd, uint8_t value);
     uint8_t (*read_data)(SDState *sd);
@@ -93,7 +94,10 @@  typedef struct SDClass {
 static inline SDState *sd_init(BlockDriverState *bs, bool is_spi)
 {
     SDState *sd = SD_CARD(object_new(TYPE_SD_CARD));
-    SD_GET_CLASS(sd)->init(sd, bs, is_spi);
+    Error *errp = NULL;
+    object_property_set_bool(OBJECT(sd), is_spi, "spi", &errp);
+    assert_no_error(errp);
+    SD_GET_CLASS(sd)->init(sd, bs);
     return sd;
 }