diff for duplicates of <20150120105335.GA15924@leverpostej> diff --git a/a/1.txt b/N1/1.txt index e55e96a..8994a78 100644 --- a/a/1.txt +++ b/N1/1.txt @@ -71,311 +71,3 @@ Ok. > > No. The reference clock rates can be probed at runtime, so they are not > specified in the DT. - -From the MMC block itself, or elsewhere? - -The reason I ask is that most common drivers specify the linkage of -clocks in the DT these days. - -> >> +Example: -> >> + mmc@1180000002000 { -> >> + compatible = "cavium,octeon-6130-mmc"; -> >> + reg = <0x11800 0x00002000 0x0 0x100>, -> >> + <0x11800 0x00000168 0x0 0x20>; -> >> + #address-cells = <1>; -> >> + #size-cells = <0>; -> >> + /* EMM irq, DMA irq */ -> >> + interrupts = <1 19>, <0 63>; -> >> + -> >> + /* The board only has a single MMC slot */ -> >> + mmc-slot@0 { -> >> + compatible = "cavium,octeon-6130-mmc-slot"; -> >> + reg = <0>; -> >> + spi-max-frequency = <20000000>; -> >> + /* bus width can be 1, 4 or 8 */ -> >> + cavium,bus-max-width = <8>; -> >> + cd-gpios = <&gpio 9 0>; -> >> + wp-gpios = <&gpio 10 0>; -> >> + power-gpios = <&gpio 8 0>; -> >> + }; -> >> + }; -> > -> [...] -> >> + -> >> +/** -> >> + * Unlock a single line in the L2 cache. -> >> + * -> >> + * @addr Physical address to unlock -> >> + * -> >> + * Return Zero on success -> >> + */ -> >> +static void l2c_unlock_line(u64 addr) -> >> +{ -> >> + char *addr_ptr = phys_to_ptr(addr); -> >> + asm volatile ( -> >> + "cache 23, %[line]" /* Unlock the line */ -> >> + :: [line] "m" (*addr_ptr)); -> >> +} -> >> + -> >> +/** -> >> + * Unlock a memory region in the L2 cache -> >> + * -> >> + * @start - start address to unlock -> >> + * @len - length to unlock in bytes -> >> + */ -> >> +static void l2c_unlock_mem_region(u64 start, u64 len) -> >> +{ -> >> + u64 end; -> >> + -> >> + /* Round start/end to cache line boundaries */ -> >> + end = ALIGN(start + len - 1, CVMX_CACHE_LINE_SIZE); -> >> + start = ALIGN(start, CVMX_CACHE_LINE_SIZE); -> >> + -> >> + while (start <= end) { -> >> + l2c_unlock_line(start); -> >> + start += CVMX_CACHE_LINE_SIZE; -> >> + } -> >> +} -> > -> > Why do you need to mess with the cache in this way within an MMC driver? -> -> Due to an imperfection in the design of the MMC bus hardware, The 2nd. -> to last cache block of a DMA read must be locked into the L2 Cache. -> Otherwise, data corruption may occur. Please note that this MMC bus -> hardware block is only ever encountered on SoCs where the L2 Cache is -> resident on the same piece of silicon. - -I see. It would be nice to have a big comment to that effect. I didn't -spot one, but maybe I missed it. - -> > To me it seems somewhat surprising that you need to do that, -> -> Your surprise was shared by many. -> -> > and again -> > surprising that you have custom functions within the MMC driver. -> > -> -> It is only used by this file, so we decided to put it here to keep -> everything in one place. - -Ok. - -> >> +static int octeon_mmc_probe(struct platform_device *pdev) -> >> +{ -> >> + union cvmx_mio_emm_cfg emm_cfg; -> >> + struct octeon_mmc_host *host; -> >> + struct resource *res; -> >> + void __iomem *base; -> >> + int mmc_irq[9]; -> >> + int i; -> >> + int ret = 0; -> >> + struct device_node *node = pdev->dev.of_node; -> >> + int found = 0; -> >> + bool cn78xx_style; -> >> + u64 t; -> >> + enum of_gpio_flags f; -> >> + -> >> + host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL); -> >> + if (!host) -> >> + return -ENOMEM; -> >> + -> >> + spin_lock_init(&host->irq_handler_lock); -> >> + sema_init(&host->mmc_serializer, 1); -> >> + -> >> + cn78xx_style = of_device_is_compatible(node, "cavium,octeon-7890-mmc"); -> >> + if (cn78xx_style) { -> >> + host->need_bootbus_lock = false; -> >> + host->big_dma_addr = true; -> >> + host->need_irq_handler_lock = true; -> >> + /* -> >> + * First seven are the EMM_INT bits 0..6, then two for -> >> + * the EMM_DMA_INT bits -> >> + */ -> >> + for (i = 0; i < 9; i++) { -> >> + mmc_irq[i] = platform_get_irq(pdev, i); -> >> + if (mmc_irq[i] < 0) -> >> + return mmc_irq[i]; -> > -> > The documentation describes two interrupts, -> -> The documentation is incorrect for the case of cn78xx_style. The -> documentation should be (and will be) corrected to reflect what each of -> these lines is used for. - -Great. - -> -> > yet here you try to acquire -> > nine. Please document which interrupts you expect (i.e. in what order -> > and what the logical function of each is), and when you expect them. -> > -> > If some interrupts might not always be present, use interrupt-names. -> > -> [...] -> >> + base = devm_ioremap_resource(&pdev->dev, res); -> >> + if (IS_ERR(base)) -> >> + return PTR_ERR(base); -> >> + host->base = (u64)base; -> > -> > I take it this can only be used on a 64-bit platform? -> -> Yes. -> -> > -> [...] -> >> + -> >> + platform_set_drvdata(pdev, host); -> >> + -> >> + node = of_get_next_child(pdev->dev.of_node, NULL); -> >> + while (node) { -> > -> > You should use for_each_child_of_node here. -> > -> > Also, you'll want to skip nodes that aren't compatible with -> > "cavium,octeon-6130-mmc-slot", and you'll probably want to log a warning -> > in that case. -> -> OK, I think those functions did not exist when the code was originally -> written. We will try to improve it here. - -Thanks, -Mark. - -> -> -> > -> >> + int r; -> >> + u32 slot; -> >> + -> >> + found = 0; -> >> + -> >> + r = of_property_read_u32(node, "reg", &slot); -> >> + if (!r) { -> > -> > If you use for_each_child_of_node, you can just skip ahead in this case, -> > rather than having 90% of this block conditional. -> > -> > e.g. -> > -> > for_each_child_of_node(pdev->dev.of_node, node) { -> > -> > if (!of_device_is_compatible(node, "cavium,octeon-6130-mmc-slot") { -> > pr_warn("sub node isn't slot: %s\n", of_node_full_name(node)); -> > continue; -> > } -> > -> > if (of_property_read_u32(node, "reg", &slot) != 0) { -> > pr_warn("Missing or invalid reg property on %s\n", -> > of_node_full_name(node)); -> > continue; -> > } -> > -> > other_stuff(); -> > not_indented(); -> > -> > } -> > -> >> + int ro_gpio, cd_gpio, pwr_gpio; -> >> + bool ro_low, cd_low, pwr_low; -> >> + u32 bus_width, max_freq, cmd_skew, dat_skew; -> >> + -> >> + r = of_property_read_u32(node, "cavium,bus-max-width", -> >> + &bus_width); -> >> + if (r) { -> >> + pr_info("Bus width not found for slot %d\n", -> >> + slot); -> >> + bus_width = 8; -> > -> > If the default assumption is 8 lanes, document that in the binding. -> > Otherwise, make this mandatory and skip the slot if this is missing from -> > the DT. -> > -> >> + } else { -> >> + switch (bus_width) { -> >> + case 1: -> >> + case 4: -> >> + case 8: -> >> + break; -> >> + default: -> >> + bus_width = 8; -> >> + break; -> >> + } -> >> + } -> > -> > Silently modifying this value is not a good idea. If you get an invalid -> > value, warn and skip the node. If the DT was wrong then you have no -> > chance of guessing better anyway. -> > -> >> + -> >> + r = of_property_read_u32(node, "cavium,cmd-clk-skew", -> >> + &cmd_skew); -> >> + if (r) -> >> + cmd_skew = 0; -> >> + -> >> + r = of_property_read_u32(node, "cavium,dat-clk-skew", -> >> + &dat_skew); -> >> + if (r) -> >> + dat_skew = 0; -> >> + -> > -> > These weren't in the binding. They need to be documented. -> > -> > -> >> + r = of_property_read_u32(node, "spi-max-frequency", -> >> + &max_freq); -> >> + if (r) { -> >> + max_freq = 52000000; -> >> + pr_info("no spi-max-frequency for slot %d, defautling to %d\n", -> > -> > s/defautling/defaulting/ -> > -> >> + slot, max_freq); -> >> + } -> >> + -> >> + ro_gpio = of_get_named_gpio_flags(node, "wp-gpios", -> >> + 0, &f); -> >> + ro_low = (ro_gpio >= 0 && f == OF_GPIO_ACTIVE_LOW); -> >> + cd_gpio = of_get_named_gpio_flags(node, "cd-gpios", -> >> + 0, &f); -> >> + cd_low = (cd_gpio >= 0 && f == OF_GPIO_ACTIVE_LOW); -> >> + pwr_gpio = of_get_named_gpio_flags(node, "power-gpios", -> >> + 0, &f); -> >> + pwr_low = (pwr_gpio >= 0 && f == OF_GPIO_ACTIVE_LOW); -> >> + -> >> + ret = octeon_init_slot(host, slot, bus_width, max_freq, -> >> + ro_gpio, cd_gpio, pwr_gpio, -> >> + ro_low, cd_low, pwr_low, -> >> + cmd_skew, dat_skew); -> >> + octeon_mmc_dbg("init slot %d, ret = %d\n", slot, ret); -> >> + if (ret) -> >> + goto err; -> >> + } -> >> + node = of_get_next_child(pdev->dev.of_node, node); -> >> + } -> >> + -> >> + return ret; -> >> + -> >> +err: -> >> + /* Disable MMC controller */ -> >> + emm_cfg.s.bus_ena = 0; -> >> + cvmx_write_csr(host->base + OCT_MIO_EMM_CFG, emm_cfg.u64); -> >> + -> >> + if (host->global_pwr_gpio >= 0) { -> >> + dev_dbg(&pdev->dev, "Global power off\n"); -> >> + gpio_set_value_cansleep(host->global_pwr_gpio, -> >> + host->global_pwr_gpio_low); -> >> + gpio_free(host->global_pwr_gpio); -> >> + } -> >> + -> >> + return ret; -> >> +} -> > -> > It's probably worth having some logging in this error path. -> > -> > Thanks, -> > Mark. -> > -> > -> -> diff --git a/a/content_digest b/N1/content_digest index e078a55..af3065f 100644 --- a/a/content_digest +++ b/N1/content_digest @@ -96,314 +96,6 @@ "> > No clocks in the DT?\n" ">\n" "> No. The reference clock rates can be probed at runtime, so they are not\n" - "> specified in the DT.\n" - "\n" - "From the MMC block itself, or elsewhere?\n" - "\n" - "The reason I ask is that most common drivers specify the linkage of\n" - "clocks in the DT these days.\n" - "\n" - "> >> +Example:\n" - "> >> + mmc@1180000002000 {\n" - "> >> + compatible = \"cavium,octeon-6130-mmc\";\n" - "> >> + reg = <0x11800 0x00002000 0x0 0x100>,\n" - "> >> + <0x11800 0x00000168 0x0 0x20>;\n" - "> >> + #address-cells = <1>;\n" - "> >> + #size-cells = <0>;\n" - "> >> + /* EMM irq, DMA irq */\n" - "> >> + interrupts = <1 19>, <0 63>;\n" - "> >> +\n" - "> >> + /* The board only has a single MMC slot */\n" - "> >> + mmc-slot@0 {\n" - "> >> + compatible = \"cavium,octeon-6130-mmc-slot\";\n" - "> >> + reg = <0>;\n" - "> >> + spi-max-frequency = <20000000>;\n" - "> >> + /* bus width can be 1, 4 or 8 */\n" - "> >> + cavium,bus-max-width = <8>;\n" - "> >> + cd-gpios = <&gpio 9 0>;\n" - "> >> + wp-gpios = <&gpio 10 0>;\n" - "> >> + power-gpios = <&gpio 8 0>;\n" - "> >> + };\n" - "> >> + };\n" - "> >\n" - "> [...]\n" - "> >> +\n" - "> >> +/**\n" - "> >> + * Unlock a single line in the L2 cache.\n" - "> >> + *\n" - "> >> + * @addr Physical address to unlock\n" - "> >> + *\n" - "> >> + * Return Zero on success\n" - "> >> + */\n" - "> >> +static void l2c_unlock_line(u64 addr)\n" - "> >> +{\n" - "> >> + char *addr_ptr = phys_to_ptr(addr);\n" - "> >> + asm volatile (\n" - "> >> + \"cache 23, %[line]\" /* Unlock the line */\n" - "> >> + :: [line] \"m\" (*addr_ptr));\n" - "> >> +}\n" - "> >> +\n" - "> >> +/**\n" - "> >> + * Unlock a memory region in the L2 cache\n" - "> >> + *\n" - "> >> + * @start - start address to unlock\n" - "> >> + * @len - length to unlock in bytes\n" - "> >> + */\n" - "> >> +static void l2c_unlock_mem_region(u64 start, u64 len)\n" - "> >> +{\n" - "> >> + u64 end;\n" - "> >> +\n" - "> >> + /* Round start/end to cache line boundaries */\n" - "> >> + end = ALIGN(start + len - 1, CVMX_CACHE_LINE_SIZE);\n" - "> >> + start = ALIGN(start, CVMX_CACHE_LINE_SIZE);\n" - "> >> +\n" - "> >> + while (start <= end) {\n" - "> >> + l2c_unlock_line(start);\n" - "> >> + start += CVMX_CACHE_LINE_SIZE;\n" - "> >> + }\n" - "> >> +}\n" - "> >\n" - "> > Why do you need to mess with the cache in this way within an MMC driver?\n" - ">\n" - "> Due to an imperfection in the design of the MMC bus hardware, The 2nd.\n" - "> to last cache block of a DMA read must be locked into the L2 Cache.\n" - "> Otherwise, data corruption may occur. Please note that this MMC bus\n" - "> hardware block is only ever encountered on SoCs where the L2 Cache is\n" - "> resident on the same piece of silicon.\n" - "\n" - "I see. It would be nice to have a big comment to that effect. I didn't\n" - "spot one, but maybe I missed it.\n" - "\n" - "> > To me it seems somewhat surprising that you need to do that,\n" - ">\n" - "> Your surprise was shared by many.\n" - ">\n" - "> > and again\n" - "> > surprising that you have custom functions within the MMC driver.\n" - "> >\n" - ">\n" - "> It is only used by this file, so we decided to put it here to keep\n" - "> everything in one place.\n" - "\n" - "Ok.\n" - "\n" - "> >> +static int octeon_mmc_probe(struct platform_device *pdev)\n" - "> >> +{\n" - "> >> + union cvmx_mio_emm_cfg emm_cfg;\n" - "> >> + struct octeon_mmc_host *host;\n" - "> >> + struct resource *res;\n" - "> >> + void __iomem *base;\n" - "> >> + int mmc_irq[9];\n" - "> >> + int i;\n" - "> >> + int ret = 0;\n" - "> >> + struct device_node *node = pdev->dev.of_node;\n" - "> >> + int found = 0;\n" - "> >> + bool cn78xx_style;\n" - "> >> + u64 t;\n" - "> >> + enum of_gpio_flags f;\n" - "> >> +\n" - "> >> + host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL);\n" - "> >> + if (!host)\n" - "> >> + return -ENOMEM;\n" - "> >> +\n" - "> >> + spin_lock_init(&host->irq_handler_lock);\n" - "> >> + sema_init(&host->mmc_serializer, 1);\n" - "> >> +\n" - "> >> + cn78xx_style = of_device_is_compatible(node, \"cavium,octeon-7890-mmc\");\n" - "> >> + if (cn78xx_style) {\n" - "> >> + host->need_bootbus_lock = false;\n" - "> >> + host->big_dma_addr = true;\n" - "> >> + host->need_irq_handler_lock = true;\n" - "> >> + /*\n" - "> >> + * First seven are the EMM_INT bits 0..6, then two for\n" - "> >> + * the EMM_DMA_INT bits\n" - "> >> + */\n" - "> >> + for (i = 0; i < 9; i++) {\n" - "> >> + mmc_irq[i] = platform_get_irq(pdev, i);\n" - "> >> + if (mmc_irq[i] < 0)\n" - "> >> + return mmc_irq[i];\n" - "> >\n" - "> > The documentation describes two interrupts,\n" - ">\n" - "> The documentation is incorrect for the case of cn78xx_style. The\n" - "> documentation should be (and will be) corrected to reflect what each of\n" - "> these lines is used for.\n" - "\n" - "Great.\n" - "\n" - ">\n" - "> > yet here you try to acquire\n" - "> > nine. Please document which interrupts you expect (i.e. in what order\n" - "> > and what the logical function of each is), and when you expect them.\n" - "> >\n" - "> > If some interrupts might not always be present, use interrupt-names.\n" - "> >\n" - "> [...]\n" - "> >> + base = devm_ioremap_resource(&pdev->dev, res);\n" - "> >> + if (IS_ERR(base))\n" - "> >> + return PTR_ERR(base);\n" - "> >> + host->base = (u64)base;\n" - "> >\n" - "> > I take it this can only be used on a 64-bit platform?\n" - ">\n" - "> Yes.\n" - ">\n" - "> >\n" - "> [...]\n" - "> >> +\n" - "> >> + platform_set_drvdata(pdev, host);\n" - "> >> +\n" - "> >> + node = of_get_next_child(pdev->dev.of_node, NULL);\n" - "> >> + while (node) {\n" - "> >\n" - "> > You should use for_each_child_of_node here.\n" - "> >\n" - "> > Also, you'll want to skip nodes that aren't compatible with\n" - "> > \"cavium,octeon-6130-mmc-slot\", and you'll probably want to log a warning\n" - "> > in that case.\n" - ">\n" - "> OK, I think those functions did not exist when the code was originally\n" - "> written. We will try to improve it here.\n" - "\n" - "Thanks,\n" - "Mark.\n" - "\n" - ">\n" - ">\n" - "> >\n" - "> >> + int r;\n" - "> >> + u32 slot;\n" - "> >> +\n" - "> >> + found = 0;\n" - "> >> +\n" - "> >> + r = of_property_read_u32(node, \"reg\", &slot);\n" - "> >> + if (!r) {\n" - "> >\n" - "> > If you use for_each_child_of_node, you can just skip ahead in this case,\n" - "> > rather than having 90% of this block conditional.\n" - "> >\n" - "> > e.g.\n" - "> >\n" - "> > for_each_child_of_node(pdev->dev.of_node, node) {\n" - "> >\n" - "> > if (!of_device_is_compatible(node, \"cavium,octeon-6130-mmc-slot\") {\n" - "> > pr_warn(\"sub node isn't slot: %s\\n\", of_node_full_name(node));\n" - "> > continue;\n" - "> > }\n" - "> >\n" - "> > if (of_property_read_u32(node, \"reg\", &slot) != 0) {\n" - "> > pr_warn(\"Missing or invalid reg property on %s\\n\",\n" - "> > of_node_full_name(node));\n" - "> > continue;\n" - "> > }\n" - "> >\n" - "> > other_stuff();\n" - "> > not_indented();\n" - "> >\n" - "> > }\n" - "> >\n" - "> >> + int ro_gpio, cd_gpio, pwr_gpio;\n" - "> >> + bool ro_low, cd_low, pwr_low;\n" - "> >> + u32 bus_width, max_freq, cmd_skew, dat_skew;\n" - "> >> +\n" - "> >> + r = of_property_read_u32(node, \"cavium,bus-max-width\",\n" - "> >> + &bus_width);\n" - "> >> + if (r) {\n" - "> >> + pr_info(\"Bus width not found for slot %d\\n\",\n" - "> >> + slot);\n" - "> >> + bus_width = 8;\n" - "> >\n" - "> > If the default assumption is 8 lanes, document that in the binding.\n" - "> > Otherwise, make this mandatory and skip the slot if this is missing from\n" - "> > the DT.\n" - "> >\n" - "> >> + } else {\n" - "> >> + switch (bus_width) {\n" - "> >> + case 1:\n" - "> >> + case 4:\n" - "> >> + case 8:\n" - "> >> + break;\n" - "> >> + default:\n" - "> >> + bus_width = 8;\n" - "> >> + break;\n" - "> >> + }\n" - "> >> + }\n" - "> >\n" - "> > Silently modifying this value is not a good idea. If you get an invalid\n" - "> > value, warn and skip the node. If the DT was wrong then you have no\n" - "> > chance of guessing better anyway.\n" - "> >\n" - "> >> +\n" - "> >> + r = of_property_read_u32(node, \"cavium,cmd-clk-skew\",\n" - "> >> + &cmd_skew);\n" - "> >> + if (r)\n" - "> >> + cmd_skew = 0;\n" - "> >> +\n" - "> >> + r = of_property_read_u32(node, \"cavium,dat-clk-skew\",\n" - "> >> + &dat_skew);\n" - "> >> + if (r)\n" - "> >> + dat_skew = 0;\n" - "> >> +\n" - "> >\n" - "> > These weren't in the binding. They need to be documented.\n" - "> >\n" - "> >\n" - "> >> + r = of_property_read_u32(node, \"spi-max-frequency\",\n" - "> >> + &max_freq);\n" - "> >> + if (r) {\n" - "> >> + max_freq = 52000000;\n" - "> >> + pr_info(\"no spi-max-frequency for slot %d, defautling to %d\\n\",\n" - "> >\n" - "> > s/defautling/defaulting/\n" - "> >\n" - "> >> + slot, max_freq);\n" - "> >> + }\n" - "> >> +\n" - "> >> + ro_gpio = of_get_named_gpio_flags(node, \"wp-gpios\",\n" - "> >> + 0, &f);\n" - "> >> + ro_low = (ro_gpio >= 0 && f == OF_GPIO_ACTIVE_LOW);\n" - "> >> + cd_gpio = of_get_named_gpio_flags(node, \"cd-gpios\",\n" - "> >> + 0, &f);\n" - "> >> + cd_low = (cd_gpio >= 0 && f == OF_GPIO_ACTIVE_LOW);\n" - "> >> + pwr_gpio = of_get_named_gpio_flags(node, \"power-gpios\",\n" - "> >> + 0, &f);\n" - "> >> + pwr_low = (pwr_gpio >= 0 && f == OF_GPIO_ACTIVE_LOW);\n" - "> >> +\n" - "> >> + ret = octeon_init_slot(host, slot, bus_width, max_freq,\n" - "> >> + ro_gpio, cd_gpio, pwr_gpio,\n" - "> >> + ro_low, cd_low, pwr_low,\n" - "> >> + cmd_skew, dat_skew);\n" - "> >> + octeon_mmc_dbg(\"init slot %d, ret = %d\\n\", slot, ret);\n" - "> >> + if (ret)\n" - "> >> + goto err;\n" - "> >> + }\n" - "> >> + node = of_get_next_child(pdev->dev.of_node, node);\n" - "> >> + }\n" - "> >> +\n" - "> >> + return ret;\n" - "> >> +\n" - "> >> +err:\n" - "> >> + /* Disable MMC controller */\n" - "> >> + emm_cfg.s.bus_ena = 0;\n" - "> >> + cvmx_write_csr(host->base + OCT_MIO_EMM_CFG, emm_cfg.u64);\n" - "> >> +\n" - "> >> + if (host->global_pwr_gpio >= 0) {\n" - "> >> + dev_dbg(&pdev->dev, \"Global power off\\n\");\n" - "> >> + gpio_set_value_cansleep(host->global_pwr_gpio,\n" - "> >> + host->global_pwr_gpio_low);\n" - "> >> + gpio_free(host->global_pwr_gpio);\n" - "> >> + }\n" - "> >> +\n" - "> >> + return ret;\n" - "> >> +}\n" - "> >\n" - "> > It's probably worth having some logging in this error path.\n" - "> >\n" - "> > Thanks,\n" - "> > Mark.\n" - "> >\n" - "> >\n" - ">\n" - > + > specified in the DT. -7c8e1b84ca3dff71b5b87aeec78db2ec0d9f3ebb39e51a7197ac4cf566a7edb8 +614e59a294351c5a32d6f9f5c1d48ad246008888c1d577c86b63a929abd4acd4
diff --git a/a/1.txt b/N2/1.txt index e55e96a..90b0d96 100644 --- a/a/1.txt +++ b/N2/1.txt @@ -72,7 +72,7 @@ Ok. > No. The reference clock rates can be probed at runtime, so they are not > specified in the DT. -From the MMC block itself, or elsewhere? +>From the MMC block itself, or elsewhere? The reason I ask is that most common drivers specify the linkage of clocks in the DT these days. diff --git a/a/content_digest b/N2/content_digest index e078a55..91b093c 100644 --- a/a/content_digest +++ b/N2/content_digest @@ -98,7 +98,7 @@ "> No. The reference clock rates can be probed at runtime, so they are not\n" "> specified in the DT.\n" "\n" - "From the MMC block itself, or elsewhere?\n" + ">From the MMC block itself, or elsewhere?\n" "\n" "The reason I ask is that most common drivers specify the linkage of\n" "clocks in the DT these days.\n" @@ -406,4 +406,4 @@ ">\n" > -7c8e1b84ca3dff71b5b87aeec78db2ec0d9f3ebb39e51a7197ac4cf566a7edb8 +e522f85fef8916f33d436eee2527d362ba037054dba07eedf31edaff7f8e7568
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.