diff mbox

[U-Boot,1/3] dm: blk: Add a way to obtain a block device from its parent

Message ID 20170527173719.25679-2-sjg@chromium.org
State Accepted
Commit 9f103b9cb5f8de4f196b5ef8f6ddb4749cd732ba
Delegated to: Jaehoon Chung
Headers show

Commit Message

Simon Glass May 27, 2017, 5:37 p.m. UTC
Many devices support a child block device (e.g. MMC, USB). Add a
convenient way to get this device given the parent device.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 drivers/block/blk-uclass.c | 26 ++++++++++++++++++++++++++
 include/blk.h              |  7 +++++++
 test/dm/blk.c              | 18 ++++++++++++++++++
 3 files changed, 51 insertions(+)

Comments

Tom Rini May 28, 2017, 11:43 a.m. UTC | #1
On Sat, May 27, 2017 at 11:37:17AM -0600, Simon Glass wrote:

> Many devices support a child block device (e.g. MMC, USB). Add a
> convenient way to get this device given the parent device.
> 
> Signed-off-by: Simon Glass <sjg@chromium.org>

Reviewed-by: Tom Rini <trini@konsulko.com>
Jaehoon Chung June 7, 2017, 3:49 a.m. UTC | #2
Hi Simon,

On 05/28/2017 02:37 AM, Simon Glass wrote:
> Many devices support a child block device (e.g. MMC, USB). Add a
> convenient way to get this device given the parent device.
> 
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
> 
>  drivers/block/blk-uclass.c | 26 ++++++++++++++++++++++++++
>  include/blk.h              |  7 +++++++
>  test/dm/blk.c              | 18 ++++++++++++++++++
>  3 files changed, 51 insertions(+)
> 
> diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c
> index 6145675271..23f131b7ad 100644
> --- a/drivers/block/blk-uclass.c
> +++ b/drivers/block/blk-uclass.c
> @@ -453,6 +453,32 @@ int blk_prepare_device(struct udevice *dev)
>  	return 0;
>  }
>  
> +int blk_get_from_parent(struct udevice *parent, struct udevice **devp)
> +{
> +	struct udevice *dev;
> +	enum uclass_id id;
> +	int ret;
> +
> +	device_find_first_child(parent, &dev);
> +	if (!dev) {
> +		debug("%s: No block device found for parent '%s'\n", __func__,
> +		      parent->name);
> +		return -ENODEV;
> +	}
> +	id = device_get_uclass_id(dev);
> +	if (id != UCLASS_BLK) {
> +		debug("%s: Incorrect uclass %s for block device '%s'\n",
> +		      __func__, uclass_get_name(id), dev->name);
> +		return -ENOTBLK;
> +	}
> +	ret = device_probe(dev);
> +	if (ret)
> +		return ret;
> +	*devp = dev;
> +
> +	return 0;
> +}
> +
>  int blk_find_max_devnum(enum if_type if_type)
>  {
>  	struct udevice *dev;
> diff --git a/include/blk.h b/include/blk.h
> index a128ee4841..4d60987f61 100644
> --- a/include/blk.h
> +++ b/include/blk.h
> @@ -616,4 +616,11 @@ ulong blk_write_devnum(enum if_type if_type, int devnum, lbaint_t start,
>   */
>  int blk_select_hwpart_devnum(enum if_type if_type, int devnum, int hwpart);
>  
> +/**
> + * blk_get_from_parent() - obtain a block device by looking up its parent
> + *
> + * All devices with
> + */
> +int blk_get_from_parent(struct udevice *parent, struct udevice **devp);

Don't need to consider whether CONFIG_BLK is defined or not?
blk_get_from_parent() is declared in blk-uclass.c

Best Regards,
Jaehoon Chung

> +
>  #endif
> diff --git a/test/dm/blk.c b/test/dm/blk.c
> index 5c5eb829a0..923e8d95f0 100644
> --- a/test/dm/blk.c
> +++ b/test/dm/blk.c
> @@ -150,3 +150,21 @@ static int dm_test_blk_devnum(struct unit_test_state *uts)
>  	return 0;
>  }
>  DM_TEST(dm_test_blk_devnum, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
> +
> +/* Test that we can get a block from its parent */
> +static int dm_test_blk_get_from_parent(struct unit_test_state *uts)
> +{
> +	struct udevice *dev, *blk;
> +
> +	ut_assertok(uclass_get_device(UCLASS_MMC, 0, &dev));
> +	ut_assertok(blk_get_from_parent(dev, &blk));
> +
> +	ut_assertok(uclass_get_device(UCLASS_I2C, 0, &dev));
> +	ut_asserteq(-ENOTBLK, blk_get_from_parent(dev, &blk));
> +
> +	ut_assertok(uclass_get_device(UCLASS_GPIO, 0, &dev));
> +	ut_asserteq(-ENODEV, blk_get_from_parent(dev, &blk));
> +
> +	return 0;
> +}
> +DM_TEST(dm_test_blk_get_from_parent, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
>
Simon Glass June 9, 2017, 3:06 a.m. UTC | #3
Hi Jaehoon,

On 6 June 2017 at 21:49, Jaehoon Chung <jh80.chung@samsung.com> wrote:
> Hi Simon,
>
> On 05/28/2017 02:37 AM, Simon Glass wrote:
>> Many devices support a child block device (e.g. MMC, USB). Add a
>> convenient way to get this device given the parent device.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>> ---
>>
>>  drivers/block/blk-uclass.c | 26 ++++++++++++++++++++++++++
>>  include/blk.h              |  7 +++++++
>>  test/dm/blk.c              | 18 ++++++++++++++++++
>>  3 files changed, 51 insertions(+)
>>
>> diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c
>> index 6145675271..23f131b7ad 100644
>> --- a/drivers/block/blk-uclass.c
>> +++ b/drivers/block/blk-uclass.c
>> @@ -453,6 +453,32 @@ int blk_prepare_device(struct udevice *dev)
>>       return 0;
>>  }
>>
>> +int blk_get_from_parent(struct udevice *parent, struct udevice **devp)
>> +{
>> +     struct udevice *dev;
>> +     enum uclass_id id;
>> +     int ret;
>> +
>> +     device_find_first_child(parent, &dev);
>> +     if (!dev) {
>> +             debug("%s: No block device found for parent '%s'\n", __func__,
>> +                   parent->name);
>> +             return -ENODEV;
>> +     }
>> +     id = device_get_uclass_id(dev);
>> +     if (id != UCLASS_BLK) {
>> +             debug("%s: Incorrect uclass %s for block device '%s'\n",
>> +                   __func__, uclass_get_name(id), dev->name);
>> +             return -ENOTBLK;
>> +     }
>> +     ret = device_probe(dev);
>> +     if (ret)
>> +             return ret;
>> +     *devp = dev;
>> +
>> +     return 0;
>> +}
>> +
>>  int blk_find_max_devnum(enum if_type if_type)
>>  {
>>       struct udevice *dev;
>> diff --git a/include/blk.h b/include/blk.h
>> index a128ee4841..4d60987f61 100644
>> --- a/include/blk.h
>> +++ b/include/blk.h
>> @@ -616,4 +616,11 @@ ulong blk_write_devnum(enum if_type if_type, int devnum, lbaint_t start,
>>   */
>>  int blk_select_hwpart_devnum(enum if_type if_type, int devnum, int hwpart);
>>
>> +/**
>> + * blk_get_from_parent() - obtain a block device by looking up its parent
>> + *
>> + * All devices with
>> + */
>> +int blk_get_from_parent(struct udevice *parent, struct udevice **devp);
>
> Don't need to consider whether CONFIG_BLK is defined or not?
> blk_get_from_parent() is declared in blk-uclass.c

Well in that case this function will not be called, so I think it is OK.

>
> Best Regards,
> Jaehoon Chung

- Simon
Jaehoon Chung June 9, 2017, 3:38 a.m. UTC | #4
On 06/09/2017 12:06 PM, Simon Glass wrote:
> Hi Jaehoon,
> 
> On 6 June 2017 at 21:49, Jaehoon Chung <jh80.chung@samsung.com> wrote:
>> Hi Simon,
>>
>> On 05/28/2017 02:37 AM, Simon Glass wrote:
>>> Many devices support a child block device (e.g. MMC, USB). Add a
>>> convenient way to get this device given the parent device.
>>>
>>> Signed-off-by: Simon Glass <sjg@chromium.org>
>>> ---
>>>
>>>  drivers/block/blk-uclass.c | 26 ++++++++++++++++++++++++++
>>>  include/blk.h              |  7 +++++++
>>>  test/dm/blk.c              | 18 ++++++++++++++++++
>>>  3 files changed, 51 insertions(+)
>>>
>>> diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c
>>> index 6145675271..23f131b7ad 100644
>>> --- a/drivers/block/blk-uclass.c
>>> +++ b/drivers/block/blk-uclass.c
>>> @@ -453,6 +453,32 @@ int blk_prepare_device(struct udevice *dev)
>>>       return 0;
>>>  }
>>>
>>> +int blk_get_from_parent(struct udevice *parent, struct udevice **devp)
>>> +{
>>> +     struct udevice *dev;
>>> +     enum uclass_id id;
>>> +     int ret;
>>> +
>>> +     device_find_first_child(parent, &dev);
>>> +     if (!dev) {
>>> +             debug("%s: No block device found for parent '%s'\n", __func__,
>>> +                   parent->name);
>>> +             return -ENODEV;
>>> +     }
>>> +     id = device_get_uclass_id(dev);
>>> +     if (id != UCLASS_BLK) {
>>> +             debug("%s: Incorrect uclass %s for block device '%s'\n",
>>> +                   __func__, uclass_get_name(id), dev->name);
>>> +             return -ENOTBLK;
>>> +     }
>>> +     ret = device_probe(dev);
>>> +     if (ret)
>>> +             return ret;
>>> +     *devp = dev;
>>> +
>>> +     return 0;
>>> +}
>>> +
>>>  int blk_find_max_devnum(enum if_type if_type)
>>>  {
>>>       struct udevice *dev;
>>> diff --git a/include/blk.h b/include/blk.h
>>> index a128ee4841..4d60987f61 100644
>>> --- a/include/blk.h
>>> +++ b/include/blk.h
>>> @@ -616,4 +616,11 @@ ulong blk_write_devnum(enum if_type if_type, int devnum, lbaint_t start,
>>>   */
>>>  int blk_select_hwpart_devnum(enum if_type if_type, int devnum, int hwpart);
>>>
>>> +/**
>>> + * blk_get_from_parent() - obtain a block device by looking up its parent
>>> + *
>>> + * All devices with
>>> + */
>>> +int blk_get_from_parent(struct udevice *parent, struct udevice **devp);
>>
>> Don't need to consider whether CONFIG_BLK is defined or not?
>> blk_get_from_parent() is declared in blk-uclass.c
> 
> Well in that case this function will not be called, so I think it is OK.

include/blk.h:624:32: warning: 'struct udevice' declared inside parameter list will not be visible outside of this definition or declaration
 int blk_get_from_parent(struct udevice *parent, struct udevice **devp);

Plz, check this.. :)

Best Regards,
Jaehoon Chung

> 
>>
>> Best Regards,
>> Jaehoon Chung
> 
> - Simon
> 
> 
>
Simon Glass June 21, 2017, 1:49 a.m. UTC | #5
Hi Jaehoon,

On 8 June 2017 at 21:38, Jaehoon Chung <jh80.chung@samsung.com> wrote:
> On 06/09/2017 12:06 PM, Simon Glass wrote:
>> Hi Jaehoon,
>>
>> On 6 June 2017 at 21:49, Jaehoon Chung <jh80.chung@samsung.com> wrote:
>>> Hi Simon,
>>>
>>> On 05/28/2017 02:37 AM, Simon Glass wrote:
>>>> Many devices support a child block device (e.g. MMC, USB). Add a
>>>> convenient way to get this device given the parent device.
>>>>
>>>> Signed-off-by: Simon Glass <sjg@chromium.org>
>>>> ---
>>>>
>>>>  drivers/block/blk-uclass.c | 26 ++++++++++++++++++++++++++
>>>>  include/blk.h              |  7 +++++++
>>>>  test/dm/blk.c              | 18 ++++++++++++++++++
>>>>  3 files changed, 51 insertions(+)
>>>>
>>>> diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c
>>>> index 6145675271..23f131b7ad 100644
>>>> --- a/drivers/block/blk-uclass.c
>>>> +++ b/drivers/block/blk-uclass.c
>>>> @@ -453,6 +453,32 @@ int blk_prepare_device(struct udevice *dev)
>>>>       return 0;
>>>>  }
>>>>
>>>> +int blk_get_from_parent(struct udevice *parent, struct udevice **devp)
>>>> +{
>>>> +     struct udevice *dev;
>>>> +     enum uclass_id id;
>>>> +     int ret;
>>>> +
>>>> +     device_find_first_child(parent, &dev);
>>>> +     if (!dev) {
>>>> +             debug("%s: No block device found for parent '%s'\n", __func__,
>>>> +                   parent->name);
>>>> +             return -ENODEV;
>>>> +     }
>>>> +     id = device_get_uclass_id(dev);
>>>> +     if (id != UCLASS_BLK) {
>>>> +             debug("%s: Incorrect uclass %s for block device '%s'\n",
>>>> +                   __func__, uclass_get_name(id), dev->name);
>>>> +             return -ENOTBLK;
>>>> +     }
>>>> +     ret = device_probe(dev);
>>>> +     if (ret)
>>>> +             return ret;
>>>> +     *devp = dev;
>>>> +
>>>> +     return 0;
>>>> +}
>>>> +
>>>>  int blk_find_max_devnum(enum if_type if_type)
>>>>  {
>>>>       struct udevice *dev;
>>>> diff --git a/include/blk.h b/include/blk.h
>>>> index a128ee4841..4d60987f61 100644
>>>> --- a/include/blk.h
>>>> +++ b/include/blk.h
>>>> @@ -616,4 +616,11 @@ ulong blk_write_devnum(enum if_type if_type, int devnum, lbaint_t start,
>>>>   */
>>>>  int blk_select_hwpart_devnum(enum if_type if_type, int devnum, int hwpart);
>>>>
>>>> +/**
>>>> + * blk_get_from_parent() - obtain a block device by looking up its parent
>>>> + *
>>>> + * All devices with
>>>> + */
>>>> +int blk_get_from_parent(struct udevice *parent, struct udevice **devp);
>>>
>>> Don't need to consider whether CONFIG_BLK is defined or not?
>>> blk_get_from_parent() is declared in blk-uclass.c
>>
>> Well in that case this function will not be called, so I think it is OK.
>
> include/blk.h:624:32: warning: 'struct udevice' declared inside parameter list will not be visible outside of this definition or declaration
>  int blk_get_from_parent(struct udevice *parent, struct udevice **devp);
>
> Plz, check this.. :)

Which board is this, please?

Regards,
Simon
diff mbox

Patch

diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c
index 6145675271..23f131b7ad 100644
--- a/drivers/block/blk-uclass.c
+++ b/drivers/block/blk-uclass.c
@@ -453,6 +453,32 @@  int blk_prepare_device(struct udevice *dev)
 	return 0;
 }
 
+int blk_get_from_parent(struct udevice *parent, struct udevice **devp)
+{
+	struct udevice *dev;
+	enum uclass_id id;
+	int ret;
+
+	device_find_first_child(parent, &dev);
+	if (!dev) {
+		debug("%s: No block device found for parent '%s'\n", __func__,
+		      parent->name);
+		return -ENODEV;
+	}
+	id = device_get_uclass_id(dev);
+	if (id != UCLASS_BLK) {
+		debug("%s: Incorrect uclass %s for block device '%s'\n",
+		      __func__, uclass_get_name(id), dev->name);
+		return -ENOTBLK;
+	}
+	ret = device_probe(dev);
+	if (ret)
+		return ret;
+	*devp = dev;
+
+	return 0;
+}
+
 int blk_find_max_devnum(enum if_type if_type)
 {
 	struct udevice *dev;
diff --git a/include/blk.h b/include/blk.h
index a128ee4841..4d60987f61 100644
--- a/include/blk.h
+++ b/include/blk.h
@@ -616,4 +616,11 @@  ulong blk_write_devnum(enum if_type if_type, int devnum, lbaint_t start,
  */
 int blk_select_hwpart_devnum(enum if_type if_type, int devnum, int hwpart);
 
+/**
+ * blk_get_from_parent() - obtain a block device by looking up its parent
+ *
+ * All devices with
+ */
+int blk_get_from_parent(struct udevice *parent, struct udevice **devp);
+
 #endif
diff --git a/test/dm/blk.c b/test/dm/blk.c
index 5c5eb829a0..923e8d95f0 100644
--- a/test/dm/blk.c
+++ b/test/dm/blk.c
@@ -150,3 +150,21 @@  static int dm_test_blk_devnum(struct unit_test_state *uts)
 	return 0;
 }
 DM_TEST(dm_test_blk_devnum, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test that we can get a block from its parent */
+static int dm_test_blk_get_from_parent(struct unit_test_state *uts)
+{
+	struct udevice *dev, *blk;
+
+	ut_assertok(uclass_get_device(UCLASS_MMC, 0, &dev));
+	ut_assertok(blk_get_from_parent(dev, &blk));
+
+	ut_assertok(uclass_get_device(UCLASS_I2C, 0, &dev));
+	ut_asserteq(-ENOTBLK, blk_get_from_parent(dev, &blk));
+
+	ut_assertok(uclass_get_device(UCLASS_GPIO, 0, &dev));
+	ut_asserteq(-ENODEV, blk_get_from_parent(dev, &blk));
+
+	return 0;
+}
+DM_TEST(dm_test_blk_get_from_parent, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);